[mutter] clutter/align-constraint: Add pivot-point property



commit 590b9b8c86972539d62bf5de6d28178cc5ea8958
Author: Jonas Dreßler <verdre v0yd nl>
Date:   Mon Jun 8 22:23:04 2020 +0200

    clutter/align-constraint: Add pivot-point property
    
    Add a new pivot-point property to the ClutterAlignConstraint, similar to
    the pivot point used by ClutterActor, defining the point in the
    constraint actor around which the aligning is applied to the actor.
    
    Just as the ClutterActor property, this property is defined using a
    GraphenePoint.
    
    By default this property remains set to (-1, -1) and the actor
    will always be aligned inside the source actor, preserving the existing
    behavior of ClutterAlignConstraint.
    
    https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/737

 clutter/clutter/clutter-align-constraint.c | 120 +++++++++++++++++++++++++++--
 clutter/clutter/clutter-align-constraint.h |   6 ++
 2 files changed, 118 insertions(+), 8 deletions(-)
---
diff --git a/clutter/clutter/clutter-align-constraint.c b/clutter/clutter/clutter-align-constraint.c
index 2da101961b..21e9ef5eac 100644
--- a/clutter/clutter/clutter-align-constraint.c
+++ b/clutter/clutter/clutter-align-constraint.c
@@ -58,6 +58,7 @@ struct _ClutterAlignConstraint
   ClutterActor *actor;
   ClutterActor *source;
   ClutterAlignAxis align_axis;
+  graphene_point_t pivot;
   gfloat factor;
 };
 
@@ -72,6 +73,7 @@ enum
 
   PROP_SOURCE,
   PROP_ALIGN_AXIS,
+  PROP_PIVOT_POINT,
   PROP_FACTOR,
 
   PROP_LAST
@@ -134,6 +136,8 @@ clutter_align_constraint_update_allocation (ClutterConstraint *constraint,
   gfloat source_width, source_height;
   gfloat actor_width, actor_height;
   gfloat source_x, source_y;
+  gfloat offset_x_start, offset_y_start;
+  gfloat pivot_x, pivot_y;
 
   if (align->source == NULL)
     return;
@@ -143,25 +147,31 @@ clutter_align_constraint_update_allocation (ClutterConstraint *constraint,
   clutter_actor_get_position (align->source, &source_x, &source_y);
   clutter_actor_get_size (align->source, &source_width, &source_height);
 
+  pivot_x = align->pivot.x == -1.f
+    ? align->factor
+    : align->pivot.x;
+  pivot_y = align->pivot.y == -1.f
+    ? align->factor
+    : align->pivot.y;
+
+  offset_x_start = pivot_x * -actor_width;
+  offset_y_start = pivot_y * -actor_height;
+
   switch (align->align_axis)
     {
     case CLUTTER_ALIGN_X_AXIS:
-      allocation->x1 = ((source_width - actor_width) * align->factor)
-                     + source_x;
+      allocation->x1 = source_x + offset_x_start + (source_width * align->factor);
       allocation->x2 = allocation->x1 + actor_width;
       break;
 
     case CLUTTER_ALIGN_Y_AXIS:
-      allocation->y1 = ((source_height - actor_height) * align->factor)
-                     + source_y;
+      allocation->y1 = source_y + offset_y_start + (source_height * align->factor);
       allocation->y2 = allocation->y1 + actor_height;
       break;
 
     case CLUTTER_ALIGN_BOTH:
-      allocation->x1 = ((source_width - actor_width) * align->factor)
-                     + source_x;
-      allocation->y1 = ((source_height - actor_height) * align->factor)
-                     + source_y;
+      allocation->x1 = source_x + offset_x_start + (source_width * align->factor);
+      allocation->y1 = source_y + offset_y_start + (source_height * align->factor);
       allocation->x2 = allocation->x1 + actor_width;
       allocation->y2 = allocation->y1 + actor_height;
       break;
@@ -211,6 +221,10 @@ clutter_align_constraint_set_property (GObject      *gobject,
       clutter_align_constraint_set_align_axis (align, g_value_get_enum (value));
       break;
 
+    case PROP_PIVOT_POINT:
+      clutter_align_constraint_set_pivot_point (align, g_value_get_boxed (value));
+      break;
+
     case PROP_FACTOR:
       clutter_align_constraint_set_factor (align, g_value_get_float (value));
       break;
@@ -239,6 +253,16 @@ clutter_align_constraint_get_property (GObject    *gobject,
       g_value_set_enum (value, align->align_axis);
       break;
 
+    case PROP_PIVOT_POINT:
+      {
+        graphene_point_t point;
+
+        clutter_align_constraint_get_pivot_point (align, &point);
+
+        g_value_set_boxed (value, &point);
+      }
+      break;
+
     case PROP_FACTOR:
       g_value_set_float (value, align->factor);
       break;
@@ -292,6 +316,30 @@ clutter_align_constraint_class_init (ClutterAlignConstraintClass *klass)
                        CLUTTER_ALIGN_X_AXIS,
                        CLUTTER_PARAM_READWRITE | G_PARAM_CONSTRUCT);
 
+  /**
+   * ClutterAlignConstraint:pivot-point:
+   *
+   * The pivot point used by the constraint. The pivot point is the
+   * point in the constraint actor around which the aligning is applied,
+   * with (0, 0) being the top left corner of the actor and (1, 1) the
+   * bottom right corner of the actor.
+   *
+   * For example, setting the pivot point to (0.5, 0.5) and using a factor
+   * of 1 for both axes will align the actors horizontal and vertical
+   * center point with the bottom right corner of the source actor.
+   *
+   * By default, the pivot point is set to (-1, -1), which means it's not
+   * used and the constrained actor will be aligned to always stay inside
+   * the source actor.
+   */
+  obj_props[PROP_PIVOT_POINT] =
+    g_param_spec_boxed ("pivot-point",
+                       P_("Pivot point"),
+                       P_("The pivot point"),
+                       GRAPHENE_TYPE_POINT,
+                       G_PARAM_READWRITE |
+                       G_PARAM_STATIC_STRINGS);
+
   /**
    * ClutterAlignConstraint:factor:
    *
@@ -324,6 +372,8 @@ clutter_align_constraint_init (ClutterAlignConstraint *self)
   self->actor = NULL;
   self->source = NULL;
   self->align_axis = CLUTTER_ALIGN_X_AXIS;
+  self->pivot.x = -1.f;
+  self->pivot.y = -1.f;
   self->factor = 0.0f;
 }
 
@@ -486,6 +536,60 @@ clutter_align_constraint_get_align_axis (ClutterAlignConstraint *align)
   return align->align_axis;
 }
 
+/**
+ * clutter_align_constraint_set_pivot_point:
+ * @align: a #ClutterAlignConstraint
+ * @pivot_point: A #GraphenePoint
+ *
+ * Sets the pivot point used by the constraint, the pivot point is the
+ * point in the constraint actor around which the aligning is applied,
+ * with (0, 0) being the top left corner of the actor and (1, 1) the
+ * bottom right corner of the actor.
+ *
+ * If -1 is used, the pivot point is unset and the constrained actor
+ * will be aligned to always stay inside the source actor.
+ */
+void
+clutter_align_constraint_set_pivot_point (ClutterAlignConstraint *align,
+                                          const graphene_point_t *pivot_point)
+{
+  g_return_if_fail (CLUTTER_IS_ALIGN_CONSTRAINT (align));
+  g_return_if_fail (pivot_point != NULL);
+  g_return_if_fail (pivot_point->x == -1.f ||
+                    (pivot_point->x >= 0.f && pivot_point->x <= 1.f));
+  g_return_if_fail (pivot_point->y == -1.f ||
+                    (pivot_point->y >= 0.f && pivot_point->y <= 1.f));
+
+  if (graphene_point_equal (&align->pivot, pivot_point))
+    return;
+
+  align->pivot = *pivot_point;
+
+  if (align->actor != NULL)
+    clutter_actor_queue_relayout (align->actor);
+
+  g_object_notify_by_pspec (G_OBJECT (align), obj_props[PROP_PIVOT_POINT]);
+}
+
+/**
+ * clutter_align_constraint_get_pivot_point
+ * @align: a #ClutterAlignConstraint
+ * @pivot_point: (out caller-allocates): return location for a #GraphenePoint
+ *
+ * Gets the pivot point used by the constraint set with
+ * clutter_align_constraint_set_pivot_point(). If no custom pivot
+ * point is set, -1 is set.
+ */
+void
+clutter_align_constraint_get_pivot_point (ClutterAlignConstraint *align,
+                                          graphene_point_t       *pivot_point)
+{
+  g_return_if_fail (CLUTTER_IS_ALIGN_CONSTRAINT (align));
+  g_return_if_fail (pivot_point != NULL);
+
+  *pivot_point = align->pivot;
+}
+
 /**
  * clutter_align_constraint_set_factor:
  * @align: a #ClutterAlignConstraint
diff --git a/clutter/clutter/clutter-align-constraint.h b/clutter/clutter/clutter-align-constraint.h
index 2a42d89209..7e316ce45e 100644
--- a/clutter/clutter/clutter-align-constraint.h
+++ b/clutter/clutter/clutter-align-constraint.h
@@ -67,6 +67,12 @@ void               clutter_align_constraint_set_align_axis (ClutterAlignConstrai
 CLUTTER_EXPORT
 ClutterAlignAxis   clutter_align_constraint_get_align_axis (ClutterAlignConstraint *align);
 CLUTTER_EXPORT
+void               clutter_align_constraint_set_pivot_point (ClutterAlignConstraint *align,
+                                                             const graphene_point_t *pivot_point);
+CLUTTER_EXPORT
+void               clutter_align_constraint_get_pivot_point (ClutterAlignConstraint *align,
+                                                             graphene_point_t       *pivot_point);
+CLUTTER_EXPORT
 void               clutter_align_constraint_set_factor     (ClutterAlignConstraint *align,
                                                             gfloat                  factor);
 CLUTTER_EXPORT


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]