diff options
author | Matthias Clasen <mclasen@redhat.com> | 2019-07-02 12:55:25 -0400 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2019-07-02 12:55:25 -0400 |
commit | 138195998d1bafe939bd3c627f6ab012842ced39 (patch) | |
tree | 2c53cdd2a1946bff0e8e3d4dae94053bd389aafe | |
parent | 0468238871033f620bed6ce1b60597f97e8261c6 (diff) | |
download | gtk+-138195998d1bafe939bd3c627f6ab012842ced39.tar.gz |
Add two grid constraints demos
-rw-r--r-- | demos/gtk-demo/constraints4.c | 178 | ||||
-rw-r--r-- | demos/gtk-demo/constraints5.c | 354 | ||||
-rw-r--r-- | demos/gtk-demo/demo.gresource.xml | 5 | ||||
-rw-r--r-- | demos/gtk-demo/meson.build | 2 |
4 files changed, 539 insertions, 0 deletions
diff --git a/demos/gtk-demo/constraints4.c b/demos/gtk-demo/constraints4.c new file mode 100644 index 0000000000..5d7a31a95a --- /dev/null +++ b/demos/gtk-demo/constraints4.c @@ -0,0 +1,178 @@ +/* Constraints/Grid + * + * GtkConstraintLayout lets you define complex layouts + * like grids. + */ + +#include <glib/gi18n.h> +#include <gtk/gtk.h> + +G_DECLARE_FINAL_TYPE (ComplexGrid, complex_grid, COMPLEX, GRID, GtkWidget) + +struct _ComplexGrid +{ + GtkWidget parent_instance; + + GtkWidget *button1, *button2, *button3; + GtkWidget *button4, *button5; +}; + +G_DEFINE_TYPE (ComplexGrid, complex_grid, GTK_TYPE_WIDGET) + +static void +complex_grid_destroy (GtkWidget *widget) +{ + ComplexGrid *self = COMPLEX_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); + g_clear_pointer (&self->button4, gtk_widget_destroy); + g_clear_pointer (&self->button5, gtk_widget_destroy); + + GTK_WIDGET_CLASS (complex_grid_parent_class)->destroy (widget); +} + +static void +complex_grid_class_init (ComplexGridClass *klass) +{ + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + + widget_class->destroy = complex_grid_destroy; + + gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_CONSTRAINT_LAYOUT); +} + +/* Layout: + * + * +--------------------------------------+ + * | +-----------+ | + * | | Child 4 | | + * | +-----------+-----------+----------+ | + * | | Child 1 | Child 2 | Child 3 | | + * | +-----------+-----------+----------+ | + * | | Child 5 | | + * | +-----------+ | + * +--------------------------------------+ + * + */ +static void +build_constraints (ComplexGrid *self, + GtkConstraintLayout *manager) +{ + GtkGridConstraint *constraint; + GtkConstraint *s; + + s = gtk_constraint_new (NULL, GTK_CONSTRAINT_ATTRIBUTE_LEFT, + GTK_CONSTRAINT_RELATION_EQ, + self->button1, GTK_CONSTRAINT_ATTRIBUTE_LEFT, + 1.0, 0.0, + GTK_CONSTRAINT_STRENGTH_REQUIRED); + gtk_constraint_layout_add_constraint (manager, s); + + s = gtk_constraint_new (self->button3, GTK_CONSTRAINT_ATTRIBUTE_RIGHT, + GTK_CONSTRAINT_RELATION_EQ, + NULL, GTK_CONSTRAINT_ATTRIBUTE_RIGHT, + 1.0, 0.0, + GTK_CONSTRAINT_STRENGTH_REQUIRED); + gtk_constraint_layout_add_constraint (manager, s); + + s = gtk_constraint_new (NULL, GTK_CONSTRAINT_ATTRIBUTE_TOP, + GTK_CONSTRAINT_RELATION_EQ, + self->button4, GTK_CONSTRAINT_ATTRIBUTE_TOP, + 1.0, 0.0, + GTK_CONSTRAINT_STRENGTH_REQUIRED); + gtk_constraint_layout_add_constraint (manager, s); + + s = gtk_constraint_new (NULL, GTK_CONSTRAINT_ATTRIBUTE_BOTTOM, + GTK_CONSTRAINT_RELATION_EQ, + self->button5, GTK_CONSTRAINT_ATTRIBUTE_BOTTOM, + 1.0, 0.0, + GTK_CONSTRAINT_STRENGTH_REQUIRED); + gtk_constraint_layout_add_constraint (manager, s); + + constraint = gtk_grid_constraint_new (); + g_object_set (constraint, "column-homogeneous", TRUE, NULL); + gtk_grid_constraint_add (constraint, self->button1, 0, 1, 0, 1); + gtk_grid_constraint_add (constraint, self->button2, 1, 2, 0, 1); + gtk_grid_constraint_add (constraint, self->button3, 2, 3, 0, 1); + gtk_grid_constraint_attach (constraint, manager); + + constraint = gtk_grid_constraint_new (); + g_object_set (constraint, "row-homogeneous", TRUE, NULL); + gtk_grid_constraint_add (constraint, self->button4, 0, 1, 0, 1); + gtk_grid_constraint_add (constraint, self->button2, 0, 1, 1, 2); + gtk_grid_constraint_add (constraint, self->button5, 0, 1, 2, 3); + gtk_grid_constraint_attach (constraint, manager); +} + +static void +complex_grid_init (ComplexGrid *self) +{ + GtkWidget *widget = GTK_WIDGET (self); + GtkLayoutManager *manager = gtk_widget_get_layout_manager (GTK_WIDGET (self)); + + 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"); + + self->button4 = gtk_button_new_with_label ("Child 4"); + gtk_widget_set_parent (self->button4, widget); + gtk_widget_set_name (self->button4, "button4"); + + self->button5 = gtk_button_new_with_label ("Child 5"); + gtk_widget_set_parent (self->button5, widget); + gtk_widget_set_name (self->button5, "button5"); + + build_constraints (self, GTK_CONSTRAINT_LAYOUT (manager)); +} + +GtkWidget * +do_constraints4 (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 (complex_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/constraints5.c b/demos/gtk-demo/constraints5.c new file mode 100644 index 0000000000..506cae6f26 --- /dev/null +++ b/demos/gtk-demo/constraints5.c @@ -0,0 +1,354 @@ +/* Constraints/Words + * + * GtkConstraintLayout lets you define big grids. + */ + +#include <glib/gi18n.h> +#include <gtk/gtk.h> + +#define WORDS_TYPE_BASE (words_base_get_type ()) +#define WORDS_TYPE_GRID (words_grid_get_type ()) +#define WORDS_TYPE_CONSTRAINT (words_constraint_get_type ()) + +typedef struct +{ + GtkWidget parent_instance; +} WordsBase; + +typedef WordsBase WordsGrid; +typedef WordsBase WordsConstraint; + +typedef GtkWidgetClass WordsBaseClass; +typedef GtkWidgetClass WordsGridClass; +typedef GtkWidgetClass WordsConstraintClass; + +G_DEFINE_TYPE (WordsBase, words_base, GTK_TYPE_WIDGET) +G_DEFINE_TYPE (WordsGrid, words_grid, WORDS_TYPE_BASE) +G_DEFINE_TYPE (WordsConstraint, words_constraint, WORDS_TYPE_BASE) + +static void +words_grid_init (WordsGrid *words) +{ +} + +static void +words_grid_class_init (WordsGridClass *class) +{ + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class); + + gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_GRID_LAYOUT); +} + +static void +words_constraint_init (WordsGrid *words) +{ +} + +static void +words_constraint_class_init (WordsConstraintClass *class) +{ + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class); + + gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_CONSTRAINT_LAYOUT); +} + +static void +word_base_dispose (GObject *object) +{ + GtkWidget *self = GTK_WIDGET (object); + GtkWidget *child; + + while ((child = gtk_widget_get_first_child (self)) != NULL) + gtk_widget_unparent (child); + + G_OBJECT_CLASS (words_base_parent_class)->dispose (object); +} + +static void +words_base_class_init (WordsBaseClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->dispose = word_base_dispose; +} + +static int num_words = 100; +static gboolean use_constraints = FALSE; + +static void +read_words (WordsBase *self) +{ + GBytes *data; + const char *words; + int left, top; + GtkWidget *child = NULL; + GtkLayoutManager *layout = gtk_widget_get_layout_manager (GTK_WIDGET (self)); + GtkGridConstraint *grid; + GtkConstraint *constraint; + int count; + int rightmost; + GtkWidget *right_child = NULL; + gboolean use_constraint = GTK_IS_CONSTRAINT_LAYOUT (layout); + + if (use_constraint) + { + grid = gtk_grid_constraint_new (); + g_object_set (grid, + "row-homogeneous", TRUE, + "column-homogeneous", FALSE, + NULL); + } + else + { + gtk_grid_layout_set_row_homogeneous (GTK_GRID_LAYOUT (layout), TRUE); + gtk_grid_layout_set_column_homogeneous (GTK_GRID_LAYOUT (layout), FALSE); + } + + data = g_resources_lookup_data ("/constraints5/words", 0, NULL); + words = g_bytes_get_data (data, NULL); + count = 0; + + rightmost = 0; + left = 0; + top = 0; + while (words && words[0]) + { + char *p = strchr (words, '\n'); + char *word; + int len; + + if (p) + { + word = strndup (words, p - words); + words = p + 1; + } + else + { + word = strdup (words); + words = NULL; + } + + len = strlen (word); + child = gtk_button_new_with_label (word); + + if (left + len > 50) + { + top++; + left = 0; + } + + gtk_widget_set_parent (child, GTK_WIDGET (self)); + + if (left + len > rightmost) + { + rightmost = left + len; + right_child = child; + } + + if (use_constraint) + { + gtk_grid_constraint_add (grid, child, + left, left + len, + top, top + 1); + if (left == 0 && top == 0) + { + constraint = gtk_constraint_new (NULL, + GTK_CONSTRAINT_ATTRIBUTE_TOP, + GTK_CONSTRAINT_RELATION_EQ, + child, + GTK_CONSTRAINT_ATTRIBUTE_TOP, + 1.0, + 0.0, + GTK_CONSTRAINT_STRENGTH_REQUIRED); + gtk_constraint_layout_add_constraint (GTK_CONSTRAINT_LAYOUT (layout), + constraint); + constraint = gtk_constraint_new (NULL, + GTK_CONSTRAINT_ATTRIBUTE_LEFT, + GTK_CONSTRAINT_RELATION_EQ, + child, + GTK_CONSTRAINT_ATTRIBUTE_LEFT, + 1.0, + 0.0, + GTK_CONSTRAINT_STRENGTH_REQUIRED); + gtk_constraint_layout_add_constraint (GTK_CONSTRAINT_LAYOUT (layout), + constraint); + } + } + else + { + GtkGridLayoutChild *grid_child = GTK_GRID_LAYOUT_CHILD (gtk_layout_manager_get_layout_child (layout, child)); + + g_object_set (grid_child, + "left-attach", left, + "top-attach", top, + "column-span", len, + "row-span", 1, + NULL); + } + + left = left + len; + count++; + + if (count >= num_words) + break; + } + + if (use_constraint) + { + constraint = gtk_constraint_new (NULL, + GTK_CONSTRAINT_ATTRIBUTE_RIGHT, + GTK_CONSTRAINT_RELATION_EQ, + right_child, + GTK_CONSTRAINT_ATTRIBUTE_RIGHT, + 1.0, + 0.0, + GTK_CONSTRAINT_STRENGTH_REQUIRED); + gtk_constraint_layout_add_constraint (GTK_CONSTRAINT_LAYOUT (layout), + constraint); + constraint = gtk_constraint_new (NULL, + GTK_CONSTRAINT_ATTRIBUTE_BOTTOM, + GTK_CONSTRAINT_RELATION_EQ, + child, + GTK_CONSTRAINT_ATTRIBUTE_BOTTOM, + 1.0, + 0.0, + GTK_CONSTRAINT_STRENGTH_REQUIRED); + gtk_constraint_layout_add_constraint (GTK_CONSTRAINT_LAYOUT (layout), + constraint); + + gtk_grid_constraint_attach (grid, GTK_CONSTRAINT_LAYOUT (layout)); + } + + g_bytes_unref (data); +} + +static void +words_base_init (WordsBase *self) +{ + read_words (self); +} + +static void +show_words (GtkWidget *parent) +{ + GtkWidget *window; + GtkWidget *header, *box, *grid, *button; + GtkWidget *swin; + + window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_window_set_transient_for (GTK_WINDOW (window), + GTK_WINDOW (gtk_widget_get_root (parent))); + gtk_window_set_modal (GTK_WINDOW (window), TRUE); + + header = gtk_header_bar_new (); + gtk_header_bar_set_title (GTK_HEADER_BAR (header), use_constraints ? "Constraints" : "Grid"); + gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), FALSE); + gtk_window_set_titlebar (GTK_WINDOW (window), header); + gtk_window_set_resizable (GTK_WINDOW (window), TRUE); + gtk_window_set_default_size (GTK_WINDOW (window), 600, 400); + + box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); + gtk_container_add (GTK_CONTAINER (window), box); + + swin = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swin), + GTK_POLICY_AUTOMATIC, + GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_propagate_natural_width (GTK_SCROLLED_WINDOW (swin), TRUE); + gtk_scrolled_window_set_propagate_natural_height (GTK_SCROLLED_WINDOW (swin), TRUE); + gtk_widget_set_hexpand (swin, TRUE); + gtk_widget_set_vexpand (swin, TRUE); + gtk_widget_set_halign (swin, GTK_ALIGN_FILL); + gtk_widget_set_valign (swin, GTK_ALIGN_FILL); + gtk_container_add (GTK_CONTAINER (box), swin); + + if (use_constraints) + grid = g_object_new (WORDS_TYPE_CONSTRAINT, NULL); + else + grid = g_object_new (WORDS_TYPE_GRID, NULL); + + gtk_widget_set_halign (swin, GTK_ALIGN_START); + gtk_widget_set_valign (swin, GTK_ALIGN_START); + + gtk_container_add (GTK_CONTAINER (swin), grid); + + button = gtk_button_new_with_label ("Close"); + gtk_container_add (GTK_CONTAINER (box), button); + g_signal_connect_swapped (button, "clicked", + G_CALLBACK (gtk_widget_destroy), window); + + gtk_widget_show (window); +} + +static void +use_constraints_cb (GtkButton *button) +{ + use_constraints = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)); +} + +static void +word_count_cb (GtkSpinButton *button) +{ + num_words = gtk_spin_button_get_value_as_int (button); +} + +GtkWidget * +do_constraints5 (GtkWidget *do_widget) +{ + static GtkWidget *window; + + if (!window) + { + GtkWidget *header, *grid, *button, *label; + + window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + + header = gtk_header_bar_new (); + gtk_header_bar_set_title (GTK_HEADER_BAR (header), "Words"); + gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), TRUE); + gtk_window_set_titlebar (GTK_WINDOW (window), header); + gtk_window_set_resizable (GTK_WINDOW (window), FALSE); + g_signal_connect (window, "destroy", + G_CALLBACK (gtk_widget_destroyed), &window); + + grid = gtk_grid_new (); + g_object_set (grid, + "margin", 12, + "row-spacing", 12, + "column-spacing", 6, + "halign", GTK_ALIGN_FILL, + "valign", GTK_ALIGN_FILL, + "hexpand", TRUE, + "vexpand", TRUE, + NULL); + gtk_container_add (GTK_CONTAINER (window), grid); + + label = gtk_label_new ("Constraints:"); + gtk_label_set_xalign (GTK_LABEL (label), 1.0); + gtk_grid_attach (GTK_GRID (grid), label, 0, 0, 1, 1); + button = gtk_check_button_new (); + g_signal_connect (button, "clicked", G_CALLBACK (use_constraints_cb), NULL); + gtk_grid_attach (GTK_GRID (grid), button, 1, 0, 1, 1); + label = gtk_label_new ("Words:"); + gtk_label_set_xalign (GTK_LABEL (label), 1.0); + gtk_grid_attach (GTK_GRID (grid), label, 0, 1, 1, 1); + button = gtk_spin_button_new_with_range (0, 1300, 1); + g_signal_connect (button, "value-changed", G_CALLBACK (word_count_cb), NULL); + gtk_spin_button_set_value (GTK_SPIN_BUTTON (button), 10); + gtk_grid_attach (GTK_GRID (grid), button, 1, 1, 1, 1); + + button = gtk_button_new_with_label ("Show"); + gtk_widget_set_halign (button, GTK_ALIGN_END); + gtk_widget_set_valign (button, GTK_ALIGN_END); + g_signal_connect_swapped (button, "clicked", + G_CALLBACK (show_words), window); + gtk_grid_attach (GTK_GRID (grid), button, 0, 2, 2, 1); + } + + 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 6b6205b6b7..5d26f15236 100644 --- a/demos/gtk-demo/demo.gresource.xml +++ b/demos/gtk-demo/demo.gresource.xml @@ -59,6 +59,9 @@ <file>cssview.css</file> <file>reset.css</file> </gresource> + <gresource prefix="/constraints5"> + <file>words</file> + </gresource> <gresource prefix="/cursors"> <file>cursors.ui</file> <file>alias_cursor.png</file> @@ -153,6 +156,8 @@ <file>constraints.c</file> <file>constraints2.c</file> <file>constraints3.c</file> + <file>constraints4.c</file> + <file>constraints5.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 b6f52cb25c..8b2c9de749 100644 --- a/demos/gtk-demo/meson.build +++ b/demos/gtk-demo/meson.build @@ -11,6 +11,8 @@ demos = files([ 'constraints.c', 'constraints2.c', 'constraints3.c', + 'constraints4.c', + 'constraints5.c', 'css_accordion.c', 'css_basics.c', 'css_blendmodes.c', |