diff options
| author | Matthias Clasen <mclasen@redhat.com> | 2019-06-26 03:35:10 +0000 |
|---|---|---|
| committer | Emmanuele Bassi <ebassi@gnome.org> | 2019-06-28 13:11:22 +0100 |
| commit | 12d45c01b016a5562dee4e60601e0fbd89b6dc26 (patch) | |
| tree | f9296cd63dc127fdedfef3ad2d9e1281cf519232 | |
| parent | fc3f4aafe549146827cad29f205b8e56c0320c99 (diff) | |
| download | gtk+-12d45c01b016a5562dee4e60601e0fbd89b6dc26.tar.gz | |
Add an interactive constraints demo
| -rw-r--r-- | demos/gtk-demo/constraints.c | 2 | ||||
| -rw-r--r-- | demos/gtk-demo/constraints2.c | 245 | ||||
| -rw-r--r-- | demos/gtk-demo/demo.gresource.xml | 1 | ||||
| -rw-r--r-- | demos/gtk-demo/meson.build | 1 |
4 files changed, 248 insertions, 1 deletions
diff --git a/demos/gtk-demo/constraints.c b/demos/gtk-demo/constraints.c index 708414f435..f48cbb8bac 100644 --- a/demos/gtk-demo/constraints.c +++ b/demos/gtk-demo/constraints.c @@ -1,4 +1,4 @@ -/* Constraints +/* Constraints/Simple * * GtkConstraintLayout provides a layout manager that uses relations * between widgets (also known as "constraints") to compute the position diff --git a/demos/gtk-demo/constraints2.c b/demos/gtk-demo/constraints2.c new file mode 100644 index 0000000000..7ec7e09520 --- /dev/null +++ b/demos/gtk-demo/constraints2.c @@ -0,0 +1,245 @@ +/* Constraints/Interactive + * + * Demonstrate how constraints can be updates during + * user interaction. + */ + +#include <glib/gi18n.h> +#include <gtk/gtk.h> + +G_DECLARE_FINAL_TYPE (InteractiveGrid, interactive_grid, INTERACTIVE, GRID, GtkWidget) + +struct _InteractiveGrid +{ + GtkWidget parent_instance; + + GtkWidget *button1, *button2; + GtkWidget *button3; + GtkConstraintGuide *guide; + GtkConstraint *constraint; +}; + +G_DEFINE_TYPE (InteractiveGrid, interactive_grid, GTK_TYPE_WIDGET) + +static void +interactive_grid_destroy (GtkWidget *widget) +{ + InteractiveGrid *self = INTERACTIVE_GRID (widget); + + g_clear_pointer (&self->button1, gtk_widget_destroy); + g_clear_pointer (&self->button2, gtk_widget_destroy); + g_clear_pointer (&self->button3, gtk_widget_destroy); + + GTK_WIDGET_CLASS (interactive_grid_parent_class)->destroy (widget); +} + +static void +interactive_grid_class_init (InteractiveGridClass *klass) +{ + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + + widget_class->destroy = interactive_grid_destroy; + + gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_CONSTRAINT_LAYOUT); +} + +static void +build_constraints (InteractiveGrid *self, + GtkConstraintLayout *manager) +{ + self->guide = g_object_new (GTK_TYPE_CONSTRAINT_GUIDE, NULL); + gtk_constraint_layout_add_guide (manager, self->guide); + + gtk_constraint_layout_add_constraint (manager, + gtk_constraint_new_constant (GTK_CONSTRAINT_TARGET (self->guide), + GTK_CONSTRAINT_ATTRIBUTE_WIDTH, + GTK_CONSTRAINT_RELATION_EQ, + 0.0, + GTK_CONSTRAINT_STRENGTH_REQUIRED)); + + gtk_constraint_layout_add_constraint (manager, + gtk_constraint_new (NULL, + GTK_CONSTRAINT_ATTRIBUTE_START, + GTK_CONSTRAINT_RELATION_EQ, + GTK_CONSTRAINT_TARGET (self->button1), + GTK_CONSTRAINT_ATTRIBUTE_START, + 1.0, + -8.0, + GTK_CONSTRAINT_STRENGTH_REQUIRED)); + gtk_constraint_layout_add_constraint (manager, + gtk_constraint_new (GTK_CONSTRAINT_TARGET (self->button1), + GTK_CONSTRAINT_ATTRIBUTE_END, + GTK_CONSTRAINT_RELATION_EQ, + GTK_CONSTRAINT_TARGET (self->guide), + GTK_CONSTRAINT_ATTRIBUTE_START, + 1.0, + 0.0, + GTK_CONSTRAINT_STRENGTH_REQUIRED)); + gtk_constraint_layout_add_constraint (manager, + gtk_constraint_new (GTK_CONSTRAINT_TARGET (self->button2), + GTK_CONSTRAINT_ATTRIBUTE_START, + GTK_CONSTRAINT_RELATION_EQ, + GTK_CONSTRAINT_TARGET (self->guide), + GTK_CONSTRAINT_ATTRIBUTE_END, + 1.0, + 0.0, + GTK_CONSTRAINT_STRENGTH_REQUIRED)); + gtk_constraint_layout_add_constraint (manager, + gtk_constraint_new (GTK_CONSTRAINT_TARGET (self->button2), + GTK_CONSTRAINT_ATTRIBUTE_END, + GTK_CONSTRAINT_RELATION_EQ, + NULL, + GTK_CONSTRAINT_ATTRIBUTE_END, + 1.0, + -8.0, + GTK_CONSTRAINT_STRENGTH_REQUIRED)); + gtk_constraint_layout_add_constraint (manager, + gtk_constraint_new (NULL, + GTK_CONSTRAINT_ATTRIBUTE_START, + GTK_CONSTRAINT_RELATION_EQ, + GTK_CONSTRAINT_TARGET (self->button3), + GTK_CONSTRAINT_ATTRIBUTE_START, + 1.0, + -8.0, + GTK_CONSTRAINT_STRENGTH_REQUIRED)); + + gtk_constraint_layout_add_constraint (manager, + gtk_constraint_new (GTK_CONSTRAINT_TARGET (self->button3), + GTK_CONSTRAINT_ATTRIBUTE_END, + GTK_CONSTRAINT_RELATION_EQ, + GTK_CONSTRAINT_TARGET (self->guide), + GTK_CONSTRAINT_ATTRIBUTE_START, + 1.0, + 0.0, + GTK_CONSTRAINT_STRENGTH_REQUIRED)); + + gtk_constraint_layout_add_constraint (manager, + gtk_constraint_new (NULL, + GTK_CONSTRAINT_ATTRIBUTE_TOP, + GTK_CONSTRAINT_RELATION_EQ, + GTK_CONSTRAINT_TARGET (self->button1), + GTK_CONSTRAINT_ATTRIBUTE_TOP, + 1.0, + -8.0, + GTK_CONSTRAINT_STRENGTH_REQUIRED)); + gtk_constraint_layout_add_constraint (manager, + gtk_constraint_new (GTK_CONSTRAINT_TARGET (self->button2), + GTK_CONSTRAINT_ATTRIBUTE_TOP, + GTK_CONSTRAINT_RELATION_EQ, + GTK_CONSTRAINT_TARGET (self->button1), + GTK_CONSTRAINT_ATTRIBUTE_BOTTOM, + 1.0, + 0.0, + GTK_CONSTRAINT_STRENGTH_REQUIRED)); + gtk_constraint_layout_add_constraint (manager, + gtk_constraint_new (GTK_CONSTRAINT_TARGET (self->button3), + GTK_CONSTRAINT_ATTRIBUTE_TOP, + GTK_CONSTRAINT_RELATION_EQ, + GTK_CONSTRAINT_TARGET (self->button2), + GTK_CONSTRAINT_ATTRIBUTE_BOTTOM, + 1.0, + 0.0, + GTK_CONSTRAINT_STRENGTH_REQUIRED)); + gtk_constraint_layout_add_constraint (manager, + gtk_constraint_new (GTK_CONSTRAINT_TARGET (self->button3), + GTK_CONSTRAINT_ATTRIBUTE_BOTTOM, + GTK_CONSTRAINT_RELATION_EQ, + NULL, + GTK_CONSTRAINT_ATTRIBUTE_BOTTOM, + 1.0, + -8.0, + GTK_CONSTRAINT_STRENGTH_REQUIRED)); +} + +static void +drag_cb (GtkGestureDrag *drag, + double offset_x, + double offset_y, + InteractiveGrid *self) +{ + GtkConstraintLayout *layout = GTK_CONSTRAINT_LAYOUT (gtk_widget_get_layout_manager (GTK_WIDGET (self))); + double x, y; + + if (self->constraint) + { + gtk_constraint_layout_remove_constraint (layout, self->constraint); + g_clear_object (&self->constraint); + } + + gtk_gesture_drag_get_start_point (drag, &x, &y); + self->constraint = gtk_constraint_new_constant (GTK_CONSTRAINT_TARGET (self->guide), + GTK_CONSTRAINT_ATTRIBUTE_LEFT, + GTK_CONSTRAINT_RELATION_EQ, + x + offset_x, + GTK_CONSTRAINT_STRENGTH_REQUIRED); + gtk_constraint_layout_add_constraint (layout, g_object_ref (self->constraint)); + gtk_widget_queue_allocate (GTK_WIDGET (self)); +} + +static void +interactive_grid_init (InteractiveGrid *self) +{ + GtkWidget *widget = GTK_WIDGET (self); + GtkGesture *drag; + + self->button1 = gtk_button_new_with_label ("Child 1"); + gtk_widget_set_parent (self->button1, widget); + gtk_widget_set_name (self->button1, "button1"); + + self->button2 = gtk_button_new_with_label ("Child 2"); + gtk_widget_set_parent (self->button2, widget); + gtk_widget_set_name (self->button2, "button2"); + + self->button3 = gtk_button_new_with_label ("Child 3"); + gtk_widget_set_parent (self->button3, widget); + gtk_widget_set_name (self->button3, "button3"); + + GtkLayoutManager *manager = gtk_widget_get_layout_manager (GTK_WIDGET (self)); + build_constraints (self, GTK_CONSTRAINT_LAYOUT (manager)); + + drag = gtk_gesture_drag_new (); + g_signal_connect (drag, "drag-update", G_CALLBACK (drag_cb), self); + gtk_widget_add_controller (GTK_WIDGET (self), GTK_EVENT_CONTROLLER (drag)); +} + +GtkWidget * +do_constraints2 (GtkWidget *do_widget) +{ + static GtkWidget *window; + + if (!window) + { + GtkWidget *header, *box, *grid, *button; + + window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_window_set_display (GTK_WINDOW (window), gtk_widget_get_display (do_widget)); + + header = gtk_header_bar_new (); + gtk_header_bar_set_title (GTK_HEADER_BAR (header), "Constraints"); + gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), FALSE); + gtk_window_set_titlebar (GTK_WINDOW (window), header); + g_signal_connect (window, "destroy", + G_CALLBACK (gtk_widget_destroyed), &window); + + box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12); + gtk_container_add (GTK_CONTAINER (window), box); + + grid = g_object_new (interactive_grid_get_type (), NULL); + gtk_widget_set_hexpand (grid, TRUE); + gtk_widget_set_vexpand (grid, TRUE); + gtk_container_add (GTK_CONTAINER (box), grid); + + button = gtk_button_new_with_label ("Close"); + gtk_container_add (GTK_CONTAINER (box), button); + gtk_widget_set_hexpand (grid, TRUE); + g_signal_connect_swapped (button, "clicked", + G_CALLBACK (gtk_widget_destroy), window); + } + + if (!gtk_widget_get_visible (window)) + gtk_widget_show (window); + else + gtk_widget_destroy (window); + + return window; +} diff --git a/demos/gtk-demo/demo.gresource.xml b/demos/gtk-demo/demo.gresource.xml index 124eeeaee4..f3d400bba3 100644 --- a/demos/gtk-demo/demo.gresource.xml +++ b/demos/gtk-demo/demo.gresource.xml @@ -151,6 +151,7 @@ <file>colorsel.c</file> <file>combobox.c</file> <file>constraints.c</file> + <file>constraints2.c</file> <file>css_accordion.c</file> <file>css_basics.c</file> <file>css_blendmodes.c</file> diff --git a/demos/gtk-demo/meson.build b/demos/gtk-demo/meson.build index e60d7e32a8..6d4bd03fad 100644 --- a/demos/gtk-demo/meson.build +++ b/demos/gtk-demo/meson.build @@ -9,6 +9,7 @@ demos = files([ 'colorsel.c', 'combobox.c', 'constraints.c', + 'constraints2.c', 'css_accordion.c', 'css_basics.c', 'css_blendmodes.c', |
