[gtk/wip/ebassi/constraint-layout] constraint editor: Allow dragging children



commit 48e6cd42559558956350620e9deb744219a1bd04
Author: Matthias Clasen <mclasen redhat com>
Date:   Mon Jul 1 04:24:26 2019 +0000

    constraint editor: Allow dragging children
    
    We add a weak constraint for the position
    and update it as the widget is dragged.

 demos/constraint-editor/constraint-view.c | 105 +++++++++++++++++++++++++++++-
 1 file changed, 103 insertions(+), 2 deletions(-)
---
diff --git a/demos/constraint-editor/constraint-view.c b/demos/constraint-editor/constraint-view.c
index eb5852a94c..7a4b094df5 100644
--- a/demos/constraint-editor/constraint-view.c
+++ b/demos/constraint-editor/constraint-view.c
@@ -22,6 +22,8 @@ struct _ConstraintView
   GtkWidget parent;
 
   GListStore *store;
+
+  GtkWidget *drag_widget;
 };
 
 G_DEFINE_TYPE (ConstraintView, constraint_view, GTK_TYPE_WIDGET);
@@ -51,13 +53,109 @@ constraint_view_class_init (ConstraintViewClass *klass)
   gtk_widget_class_set_css_name (widget_class, "constraintview");
 }
 
+static void
+update_weak_position (ConstraintView *self,
+                      GtkWidget      *child,
+                      double          x,
+                      double          y)
+{
+  GtkLayoutManager *manager;
+  GtkConstraint *constraint;
+
+  manager = gtk_widget_get_layout_manager (GTK_WIDGET (self));
+  constraint = (GtkConstraint *)g_object_get_data (G_OBJECT (child), "x-constraint");
+  if (constraint)
+    {
+      gtk_constraint_layout_remove_constraint (GTK_CONSTRAINT_LAYOUT (manager),
+                                               constraint);
+      g_object_set_data (G_OBJECT (child), "x-constraint", NULL);
+    }
+  constraint = gtk_constraint_new_constant (child,
+                                            GTK_CONSTRAINT_ATTRIBUTE_CENTER_X,
+                                            GTK_CONSTRAINT_RELATION_EQ,
+                                            x,
+                                            GTK_CONSTRAINT_STRENGTH_WEAK);
+  gtk_constraint_layout_add_constraint (GTK_CONSTRAINT_LAYOUT (manager),
+                                        constraint);
+  g_object_set_data (G_OBJECT (child), "x-constraint", constraint);
+
+  constraint = (GtkConstraint *)g_object_get_data (G_OBJECT (child), "y-constraint");
+  if (constraint)
+    {
+      gtk_constraint_layout_remove_constraint (GTK_CONSTRAINT_LAYOUT (manager),
+                                               constraint);
+      g_object_set_data (G_OBJECT (child), "y-constraint", NULL);
+    }
+  constraint = gtk_constraint_new_constant (child,
+                                            GTK_CONSTRAINT_ATTRIBUTE_CENTER_Y,
+                                            GTK_CONSTRAINT_RELATION_EQ,
+                                            y,
+                                            GTK_CONSTRAINT_STRENGTH_WEAK);
+  gtk_constraint_layout_add_constraint (GTK_CONSTRAINT_LAYOUT (manager),
+                                        constraint);
+  g_object_set_data (G_OBJECT (child), "y-constraint", constraint);
+}
+
+static void
+drag_begin (GtkGestureDrag *drag,
+            double          start_x,
+            double          start_y,
+            ConstraintView *self)
+{
+  GtkWidget *widget;
+
+  widget = gtk_widget_pick (GTK_WIDGET (self), start_x, start_y, GTK_PICK_DEFAULT);
+
+  if (GTK_IS_LABEL (widget))
+    {
+      widget = gtk_widget_get_ancestor (widget, GTK_TYPE_FRAME);
+      if (widget &&
+          gtk_widget_get_parent (widget) == (GtkWidget *)self)
+        {
+          self->drag_widget = widget;
+        }
+    }
+}
+
+static void
+drag_update (GtkGestureDrag *drag,
+             double          offset_x,
+             double          offset_y,
+             ConstraintView *self)
+{
+  double x, y;
+
+  if (!self->drag_widget)
+    return;
+
+  gtk_gesture_drag_get_start_point (drag, &x, &y);
+  update_weak_position (self, self->drag_widget, x + offset_x, y + offset_y);
+}
+
+static void
+drag_end (GtkGestureDrag *drag,
+          double          offset_x,
+          double          offset_y,
+          ConstraintView *self)
+{
+  self->drag_widget = NULL;
+}
+
 static void
 constraint_view_init (ConstraintView *self)
 {
+  GtkEventController *controller;
+
   gtk_widget_set_layout_manager (GTK_WIDGET (self),
                                  gtk_constraint_layout_new ());
 
   self->store = g_list_store_new (G_TYPE_OBJECT);
+
+  controller = (GtkEventController *)gtk_gesture_drag_new ();
+  g_signal_connect (controller, "drag-begin", G_CALLBACK (drag_begin), self);
+  g_signal_connect (controller, "drag-update", G_CALLBACK (drag_update), self);
+  g_signal_connect (controller, "drag-end", G_CALLBACK (drag_end), self);
+  gtk_widget_add_controller (GTK_WIDGET (self), controller);
 }
 
 ConstraintView *
@@ -80,6 +178,8 @@ constraint_view_add_child (ConstraintView *view,
   gtk_container_add (GTK_CONTAINER (frame), label);
   gtk_widget_set_parent (frame, GTK_WIDGET (view));
 
+  update_weak_position (view, frame, 100, 100);
+
   g_list_store_append (view->store, frame);
 }
 
@@ -118,7 +218,7 @@ constraint_view_add_guide (ConstraintView *view,
   gtk_style_context_add_class (gtk_widget_get_style_context (frame), "guide");
   g_object_set_data_full (G_OBJECT (frame), "name", g_strdup (name), g_free);
   gtk_container_add (GTK_CONTAINER (frame), label);
-  gtk_widget_set_parent (frame, GTK_WIDGET (view));
+  gtk_widget_insert_after (frame, GTK_WIDGET (view), NULL);
 
   g_object_set_data (G_OBJECT (guide), "frame", frame);
   g_object_set_data (G_OBJECT (guide), "label", label);
@@ -169,9 +269,10 @@ constraint_view_add_guide (ConstraintView *view,
                                    GTK_CONSTRAINT_STRENGTH_REQUIRED);
   gtk_constraint_layout_add_constraint (GTK_CONSTRAINT_LAYOUT (manager),
                                         constraint);
-
   g_object_set_data (G_OBJECT (guide), "height-constraint", constraint);
 
+  update_weak_position (view, frame, 150, 150);
+
   g_list_store_append (view->store, guide);
 }
 


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