[gtk/matthiasc/lottie] Introduce point types
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/matthiasc/lottie] Introduce point types
- Date: Sun, 22 Nov 2020 06:37:47 +0000 (UTC)
commit 24912ce5b3f77c2cc558c03eb91f91b6ac272eae
Author: Matthias Clasen <mclasen redhat com>
Date: Sun Nov 22 00:52:20 2020 -0500
Introduce point types
This is a bit more organized than the ad hoc
smooth and symmetric booleans, and will let us
introduce more types in the future.
tests/curve-editor.c | 165 ++++++++++++++++++++++++++-------------------------
1 file changed, 85 insertions(+), 80 deletions(-)
---
diff --git a/tests/curve-editor.c b/tests/curve-editor.c
index 4975ae2c14..fe5ab1492a 100644
--- a/tests/curve-editor.c
+++ b/tests/curve-editor.c
@@ -42,6 +42,42 @@ op_from_string (const char *s)
g_assert_not_reached ();
}
+typedef enum
+{
+ CUSP,
+ SMOOTH,
+ SYMMETRIC
+} PointType;
+
+static const char *
+point_type_to_string (PointType type)
+{
+ switch (type)
+ {
+ case CUSP:
+ return "cusp";
+ case SMOOTH:
+ return "smooth";
+ case SYMMETRIC:
+ return "symmetric";
+ default:
+ g_assert_not_reached ();
+ }
+}
+
+static PointType
+point_type_from_string (const char *s)
+{
+ if (strcmp (s, "cusp") == 0)
+ return CUSP;
+ else if (strcmp (s, "smooth") == 0)
+ return SMOOTH;
+ else if (strcmp (s, "symmetric") == 0)
+ return SYMMETRIC;
+ else
+ g_assert_not_reached ();
+}
+
/* We don't store Bezier segments, but an array of points on
* the line. Each point comes with its two neighboring control
* points, so each Bezier segment contains p[1] and p[2] from
@@ -53,9 +89,8 @@ typedef struct
{
/* 0 and 2 are control points, 1 is the point on the line */
graphene_point_t p[3];
+ PointType type;
gboolean edit;
- gboolean smooth;
- gboolean symmetric;
int dragged;
int hovered;
/* refers to the segment following the point */
@@ -414,48 +449,35 @@ maintain_smoothness (CurveEditor *self,
{
PointData *pd;
Operation op, op1;
- graphene_point_t *p;
+ graphene_point_t *p, *c, *c2, *p2;
+ float d;
pd = &self->points[point];
- if (!pd->smooth)
+ if (pd->type == CUSP)
return;
op = pd->op;
op1 = self->points[(point - 1 + self->n_points) % self->n_points].op;
p = &pd->p[1];
+ c = &pd->p[0];
+ c2 = &pd->p[2];
if (op == CURVE && op1 == CURVE)
{
- graphene_point_t *c, *c2;
- float d;
-
- c = &pd->p[0];
- c2 = &pd->p[2];
-
d = graphene_point_distance (c, p, NULL, NULL);
opposite_point (p, c2, d, c);
}
else if (op == CURVE && op1 == LINE)
{
- graphene_point_t *c, *p2;
- float d;
-
- c = &pd->p[2];
p2 = &self->points[(point - 1 + self->n_points) % self->n_points].p[1];
-
- d = graphene_point_distance (c, p, NULL, NULL);
- opposite_point (p, p2, d, c);
+ d = graphene_point_distance (c2, p, NULL, NULL);
+ opposite_point (p, p2, d, c2);
}
else if (op == LINE && op1 == CURVE)
{
- graphene_point_t *c, *p2;
- float d;
-
- c = &pd->p[0];
p2 = &self->points[(point + 1) % self->n_points].p[1];
-
d = graphene_point_distance (c, p, NULL, NULL);
opposite_point (p, p2, d, c);
}
@@ -471,7 +493,7 @@ maintain_symmetry (CurveEditor *self,
pd = &self->points[point];
- if (!pd->symmetric)
+ if (pd->type != SYMMETRIC)
return;
c = &pd->p[0];
@@ -491,7 +513,7 @@ maintain_symmetry (CurveEditor *self,
}
/* Check if the points arount point currently satisfy
- * smoothness conditions. Set PointData.smooth accordingly.
+ * smoothness conditions. Set PointData.type accordingly.
*/
static void
check_smoothness (CurveEditor *self,
@@ -519,10 +541,10 @@ check_smoothness (CurveEditor *self,
else
p1 = NULL;
- if (p1 && p2)
- pd->smooth = collinear (&pd->p[1], p1, p2);
+ if (!p1 || !p2 || !collinear (&pd->p[1], p1, p2))
+ pd->type = CUSP;
else
- pd->smooth = TRUE;
+ pd->type = SMOOTH;
}
static void
@@ -553,7 +575,7 @@ insert_point (CurveEditor *self,
point1 = (point + 1) % self->n_points;
point2 = (point + 2) % self->n_points;
- self->points[point1].smooth = TRUE;
+ self->points[point1].type = SMOOTH;
self->points[point1].hovered = -1;
if (op == LINE)
@@ -808,7 +830,7 @@ drag_update (GtkGestureDrag *gesture,
/* the other endpoint of the line */
p = &pd1->p[1];
- if (op == CURVE && pd->smooth)
+ if (op == CURVE && pd->type != CUSP)
{
/* adjust the control point after the line segment */
opposite_point (d, p, l2, &pd->p[2]);
@@ -824,7 +846,7 @@ drag_update (GtkGestureDrag *gesture,
op11 = self->points[((self->dragged - 2 + self->n_points) % self->n_points)].op;
- if (op11 == CURVE && pd1->smooth)
+ if (op11 == CURVE && pd1->type != CUSP)
{
double l;
@@ -839,7 +861,7 @@ drag_update (GtkGestureDrag *gesture,
/* the other endpoint of the line */
p = &pd2->p[1];
- if (op1 == CURVE && pd->smooth)
+ if (op1 == CURVE && pd->type != CUSP)
{
/* adjust the control point before the line segment */
opposite_point (d, p, l1, &pd->p[0]);
@@ -853,7 +875,7 @@ drag_update (GtkGestureDrag *gesture,
pd->p[2].x += dx;
pd->p[2].y += dy;
- if (op2 == CURVE && pd2->smooth)
+ if (op2 == CURVE && pd2->type != CUSP)
{
double l;
@@ -900,7 +922,7 @@ drag_update (GtkGestureDrag *gesture,
else
g_assert_not_reached ();
- if (op == CURVE && pd->smooth)
+ if (op == CURVE && pd->type != CUSP)
{
if (op1 == CURVE)
{
@@ -911,7 +933,7 @@ drag_update (GtkGestureDrag *gesture,
d->y = y;
/* then adjust the other control point */
- if (pd->symmetric)
+ if (pd->type == SYMMETRIC)
l = graphene_point_distance (d, p, NULL, NULL);
else
l = graphene_point_distance (c, p, NULL, NULL);
@@ -951,28 +973,15 @@ drag_end (GtkGestureDrag *gesture,
/* }}} */
/* {{{ Action callbacks */
static void
-set_smooth (GSimpleAction *action,
- GVariant *value,
- gpointer data)
+set_point_type (GSimpleAction *action,
+ GVariant *value,
+ gpointer data)
{
CurveEditor *self = CURVE_EDITOR (data);
- self->points[self->context].smooth = g_variant_get_boolean (value);
+ self->points[self->context].type = point_type_from_string (g_variant_get_string (value, NULL));
maintain_smoothness (self, self->context);
-
- gtk_widget_queue_draw (GTK_WIDGET (self));
-}
-
-static void
-set_symmetric (GSimpleAction *action,
- GVariant *value,
- gpointer data)
-{
- CurveEditor *self = CURVE_EDITOR (data);
-
- self->points[self->context].symmetric = g_variant_get_boolean (value);
-
maintain_symmetry (self, self->context);
gtk_widget_queue_draw (GTK_WIDGET (self));
@@ -1042,23 +1051,10 @@ pressed (GtkGestureClick *gesture,
self->context = i;
- action = g_action_map_lookup_action (self->actions, "smooth");
- g_simple_action_set_state (G_SIMPLE_ACTION (action), g_variant_new_boolean (pd->smooth));
-
- action = g_action_map_lookup_action (self->actions, "symmetric");
- if (pd->smooth)
- {
- g_simple_action_set_enabled (G_SIMPLE_ACTION (action), TRUE);
- g_simple_action_set_state (G_SIMPLE_ACTION (action), g_variant_new_boolean
(pd->symmetric));
- }
- else
- {
- g_simple_action_set_enabled (G_SIMPLE_ACTION (action), FALSE);
- g_simple_action_set_state (G_SIMPLE_ACTION (action), FALSE);
- }
+ action = g_action_map_lookup_action (self->actions, "type");
+ g_simple_action_set_state (G_SIMPLE_ACTION (action), g_variant_new_string
(point_type_to_string (pd->type)));
action = g_action_map_lookup_action (self->actions, "operation");
-
g_simple_action_set_state (G_SIMPLE_ACTION (action), g_variant_new_string (op_to_string
(pd->op)));
gtk_popover_set_pointing_to (GTK_POPOVER (self->menu),
@@ -1265,7 +1261,7 @@ curve_editor_snapshot (GtkWidget *widget,
if (j == pd->hovered)
continue;
- if (!(j == 1 && pd->smooth))
+ if (!(j == 1 && pd->type != CUSP))
continue;
break;
@@ -1273,7 +1269,7 @@ curve_editor_snapshot (GtkWidget *widget,
if (j == pd->hovered)
continue;
- if (!(j == 1 && !pd->smooth))
+ if (!(j == 1 && pd->type == CUSP))
continue;
break;
@@ -1406,13 +1402,8 @@ curve_editor_init (CurveEditor *self)
self->actions = G_ACTION_MAP (g_simple_action_group_new ());
- action = g_simple_action_new_stateful ("smooth", NULL, g_variant_new_boolean (FALSE));
- g_signal_connect (action, "change-state", G_CALLBACK (set_smooth), self);
- g_action_map_add_action (G_ACTION_MAP (self->actions), G_ACTION (action));
- gtk_widget_insert_action_group (GTK_WIDGET (self), "point", G_ACTION_GROUP (self->actions));
-
- action = g_simple_action_new_stateful ("symmetric", NULL, g_variant_new_boolean (FALSE));
- g_signal_connect (action, "change-state", G_CALLBACK (set_symmetric), self);
+ action = g_simple_action_new_stateful ("type", G_VARIANT_TYPE_STRING, g_variant_new_string ("smooth"));
+ g_signal_connect (action, "change-state", G_CALLBACK (set_point_type), self);
g_action_map_add_action (G_ACTION_MAP (self->actions), G_ACTION (action));
gtk_widget_insert_action_group (GTK_WIDGET (self), "point", G_ACTION_GROUP (self->actions));
@@ -1428,14 +1419,23 @@ curve_editor_init (CurveEditor *self)
menu = g_menu_new ();
- item = g_menu_item_new ("Smooth", "point.smooth");
- g_menu_append_item (menu, item);
+ section = g_menu_new ();
+
+ item = g_menu_item_new ("Cusp", "point.type::cusp");
+ g_menu_append_item (section, item);
+ g_object_unref (item);
+
+ item = g_menu_item_new ("Smooth", "point.type::smooth");
+ g_menu_append_item (section, item);
g_object_unref (item);
- item = g_menu_item_new ("Symmetric", "point.symmetric");
- g_menu_append_item (menu, item);
+ item = g_menu_item_new ("Symmetric", "point.type::symmetric");
+ g_menu_append_item (section, item);
g_object_unref (item);
+ g_menu_append_section (menu, NULL, G_MENU_MODEL (section));
+ g_object_unref (section);
+
section = g_menu_new ();
item = g_menu_item_new ("Move", "point.operation::move");
@@ -1453,10 +1453,15 @@ curve_editor_init (CurveEditor *self)
g_menu_append_section (menu, NULL, G_MENU_MODEL (section));
g_object_unref (section);
+ section = g_menu_new ();
+
item = g_menu_item_new ("Remove", "point.remove");
g_menu_append_item (section, item);
g_object_unref (item);
+ g_menu_append_section (menu, NULL, G_MENU_MODEL (section));
+ g_object_unref (section);
+
self->menu = gtk_popover_menu_new_from_model (G_MENU_MODEL (menu));
g_object_unref (menu);
@@ -1515,7 +1520,7 @@ curve_editor_set_path (CurveEditor *self,
self->points = g_new0 (PointData, self->n_points);
for (i = 0; i < self->n_points; i++)
{
- self->points[i].smooth = FALSE;
+ self->points[i].type = CUSP;
self->points[i].hovered = -1;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]