diff options
Diffstat (limited to 'demos/gtk-demo/constraints3.c')
-rw-r--r-- | demos/gtk-demo/constraints3.c | 355 |
1 files changed, 355 insertions, 0 deletions
diff --git a/demos/gtk-demo/constraints3.c b/demos/gtk-demo/constraints3.c new file mode 100644 index 0000000000..d88110b96f --- /dev/null +++ b/demos/gtk-demo/constraints3.c @@ -0,0 +1,355 @@ +/* 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 ("/constraints3/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_constraint_layout_add_grid_constraint (GTK_CONSTRAINT_LAYOUT (layout), + grid); + } + + 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_constraints3 (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; +} |