From 48e6cd42559558956350620e9deb744219a1bd04 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Mon, 1 Jul 2019 04:24:26 +0000 Subject: [PATCH] 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); }