[gtk/matthiasc/lottie] Add an automatic point type
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/matthiasc/lottie] Add an automatic point type
- Date: Sun, 22 Nov 2020 06:41:38 +0000 (UTC)
commit 244364b3dcfe6e6479a5867c49e6bd58e61c884a
Author: Matthias Clasen <mclasen redhat com>
Date: Sun Nov 22 01:13:30 2020 -0500
Add an automatic point type
Points of this type update their control
points when their neighboring points (or
the point itself) move.
This is modeled on what Inkscape does.
tests/curve-editor.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 57 insertions(+), 1 deletion(-)
---
diff --git a/tests/curve-editor.c b/tests/curve-editor.c
index fe5ab1492a..8fc7c4d8e2 100644
--- a/tests/curve-editor.c
+++ b/tests/curve-editor.c
@@ -46,7 +46,8 @@ typedef enum
{
CUSP,
SMOOTH,
- SYMMETRIC
+ SYMMETRIC,
+ AUTO
} PointType;
static const char *
@@ -60,6 +61,8 @@ point_type_to_string (PointType type)
return "smooth";
case SYMMETRIC:
return "symmetric";
+ case AUTO:
+ return "auto";
default:
g_assert_not_reached ();
}
@@ -74,6 +77,8 @@ point_type_from_string (const char *s)
return SMOOTH;
else if (strcmp (s, "symmetric") == 0)
return SYMMETRIC;
+ else if (strcmp (s, "auto") == 0)
+ return AUTO;
else
g_assert_not_reached ();
}
@@ -512,6 +517,46 @@ maintain_symmetry (CurveEditor *self,
}
}
+/* Make the line through the control points perpendicular
+ * to the line bisecting the angle between neighboring
+ * points, and make the lengths 1/3 of the distance to
+ * the corresponding neighboring points.
+ */
+static void
+update_automatic (CurveEditor *self,
+ int point)
+{
+ PointData *pd, *pd1, *pd2;
+ double l1, l2;
+ graphene_point_t a;
+
+ pd = &self->points[point];
+
+ if (pd->type != AUTO)
+ return;
+
+ pd1 = &self->points[(point - 1 + self->n_points) % self->n_points];
+ pd2 = &self->points[(point + 1) % self->n_points];
+
+ l1 = graphene_point_distance (&pd->p[1], &pd1->p[1], NULL, NULL);
+ l2 = graphene_point_distance (&pd->p[1], &pd2->p[1], NULL, NULL);
+
+ a.x = pd2->p[1].x + (pd->p[1].x - pd1->p[1].x);
+ a.y = pd2->p[1].y + (pd->p[1].y - pd1->p[1].y);
+
+ scale_point (&pd->p[1], &a, l2/3, &pd->p[2]);
+ opposite_point (&pd->p[1], &a, l1/3, &pd->p[0]);
+}
+
+static void
+maintain_automatic (CurveEditor *self,
+ int point)
+{
+ update_automatic (self, point);
+ update_automatic (self, (point - 1 + self->n_points) % self->n_points);
+ update_automatic (self, (point + 1) % self->n_points);
+}
+
/* Check if the points arount point currently satisfy
* smoothness conditions. Set PointData.type accordingly.
*/
@@ -609,6 +654,8 @@ insert_point (CurveEditor *self,
else
g_assert_not_reached ();
+ maintain_automatic (self, self->context);
+
gtk_widget_queue_draw (GTK_WIDGET (self));
}
/* }}} */
@@ -892,6 +939,8 @@ drag_update (GtkGestureDrag *gesture,
pd->p[2].x += dx;
pd->p[2].y += dy;
}
+
+ maintain_automatic (self, self->dragged);
}
else
{
@@ -983,6 +1032,7 @@ set_point_type (GSimpleAction *action,
maintain_smoothness (self, self->context);
maintain_symmetry (self, self->context);
+ maintain_automatic (self, self->context);
gtk_widget_queue_draw (GTK_WIDGET (self));
}
@@ -1020,6 +1070,7 @@ remove_point (GSimpleAction *action,
self->n_points -= 1;
maintain_smoothness (self, self->context);
+ maintain_automatic (self, self->context);
gtk_widget_queue_draw (GTK_WIDGET (self));
}
@@ -1433,6 +1484,11 @@ curve_editor_init (CurveEditor *self)
g_menu_append_item (section, item);
g_object_unref (item);
+ item = g_menu_item_new ("Automatic", "point.type::auto");
+ g_menu_append_item (section, item);
+ g_object_unref (item);
+
+
g_menu_append_section (menu, NULL, G_MENU_MODEL (section));
g_object_unref (section);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]