1 /* testextendedlayout.c
2 * Copyright (C) 2007 Mathias Hasselmann <mathias.hasselmann@gmx.de>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
27 #ifdef GDK_WINDOWING_X11
31 #define IS_VALID_BASELINE(Baseline) ((Baseline) >= 0)
33 typedef enum _GuideType GuideType;
34 typedef enum _TestResult TestResult;
36 typedef struct _Guide Guide;
38 typedef struct _TestCase TestCase;
39 typedef struct _TestSuite TestSuite;
43 GUIDE_FLAGS_HORIZONTAL = (1 << 0),
44 GUIDE_FLAGS_VERTICAL = (1 << 1)
51 GUIDE_INTERIOUR_VERTICAL,
52 GUIDE_INTERIOUR_HORIZONTAL,
55 GUIDE_EXTERIOUR_VERTICAL,
56 GUIDE_EXTERIOUR_HORIZONTAL,
69 RESULT_COLUMN_MESSAGE,
80 TEST_COLUMN_TEST_CASE,
81 TEST_COLUMN_HAS_TEST_CASE,
82 TEST_COLUMN_PAGE_INDEX,
105 GtkTreeSelection *selection;
106 GtkWidget *test_current_button;
111 GtkWidget *baselines;
112 GtkWidget *interiour;
113 GtkWidget *exteriour;
114 GtkWidget *statusbar;
116 GtkTreeStore *results;
117 GtkWidget *results_view;
129 static const gchar lorem_ipsum[] =
130 "<span weight=\"bold\" size=\"xx-large\">"
131 "Lorem ipsum</span> dolor sit amet, consectetuer "
132 "adipiscing elit. Aliquam sed erat. Proin lectus "
133 "orci, venenatis pharetra, egestas id, tincidunt "
134 "vel, eros. Integer fringilla. Aenean justo ipsum, "
135 "luctus ut, volutpat laoreet, vehicula in, libero.";
137 const gchar *captions[] =
139 "<span size='xx-small'>xx-Small</span>",
140 "<span weight='bold'>Bold</span>",
141 "<span size='large'>Large</span>",
142 "<span size='xx-large'>xx-Large</span>",
146 static char * mask_xpm[] =
151 " # # # # # # # # # #",
152 "# # # # # # # # # # ",
153 " # # # # # # # # # #",
154 "# # # # # # # # # # ",
155 " # # # # # # # # # #",
156 "# # # # # # # # # # ",
157 " # # # # # # # # # #",
158 "# # # # # # # # # # ",
159 " # # # # # # # # # #",
160 "# # # # # # # # # # ",
161 " # # # # # # # # # #",
162 "# # # # # # # # # # ",
163 " # # # # # # # # # #",
164 "# # # # # # # # # # ",
165 " # # # # # # # # # #",
166 "# # # # # # # # # # ",
167 " # # # # # # # # # #",
168 "# # # # # # # # # # ",
169 " # # # # # # # # # #",
170 "# # # # # # # # # # "
173 static gint8 dashes[] = { 1, 5 };
176 set_widget_name (GtkWidget *widget,
183 va_start (args, format);
184 name = g_strdup_vprintf (format, args);
187 for(dash = name; NULL != (dash = strchr (dash, ' ')); )
190 gtk_widget_set_name (widget, name);
195 guide_new (GtkWidget *widget,
199 Guide* self = g_new0 (Guide, 1);
201 self->widget = widget;
209 test_case_new (TestSuite *suite,
214 TestCase* self = g_new0 (TestCase, 1);
218 self->detail = detail;
219 self->widget = widget;
225 update_status (TestSuite *suite,
228 const gchar *widget_name = gtk_widget_get_name (child);
229 const gchar *type_name = G_OBJECT_TYPE_NAME (child);
230 GString *status = g_string_new (type_name);
232 if (strcmp (widget_name, type_name))
233 g_string_append_printf (status, " (%s)", widget_name);
235 g_string_append_printf (status,
236 "@%p:\nposition=%dx%d; size=%dx%d; requisition=%dx%d",
240 child->allocation.width,
241 child->allocation.height,
242 child->requisition.width,
243 child->requisition.height);
245 if (GTK_IS_EXTENDED_LAYOUT (child))
247 GtkExtendedLayout *layout = (GtkExtendedLayout*) child;
248 GtkRequisition min_size, nat_size;
249 gint min_height, nat_height;
250 gint min_width, nat_width;
252 gtk_extended_layout_get_desired_size (layout, &min_size, &nat_size);
253 g_string_append_printf (status, "; minimal-size: %dx%d, natural-size: %dx%d",
254 min_size.width, min_size.height,
255 nat_size.width, nat_size.height);
257 gtk_extended_layout_get_height_for_width (layout,
258 child->allocation.width,
259 &min_height, &nat_height);
260 g_string_append_printf (status, "; height-for-%d: minimal: %d, natural: %d",
261 child->allocation.width, min_height, nat_height);
263 gtk_extended_layout_get_width_for_height (layout,
264 child->allocation.height,
265 &min_width, &nat_width);
266 g_string_append_printf (status, "; width-for-%d: minimal: %d, natural: %d",
267 child->allocation.height, min_width, nat_width);
271 gtk_label_set_text (GTK_LABEL (suite->statusbar), status->str);
272 g_string_free (status, TRUE);
276 item_activate_cb (GtkWidget *item,
279 GtkWidget *widget = data;
282 test = g_object_get_data (G_OBJECT (widget), "test-case");
283 update_status (test->suite, widget);
284 test->suite->current = widget;
286 gtk_widget_queue_draw (test->widget);
290 test_case_append_guide (TestCase *self,
295 const gchar *widget_name;
296 const gchar *type_name;
302 guide = guide_new (widget, type, group);
303 self->guides = g_list_append (self->guides, guide);
304 g_object_set_data (G_OBJECT (widget), "test-case", self);
306 widget_name = gtk_widget_get_name (widget);
307 type_name = G_OBJECT_TYPE_NAME (widget);
309 item_label = g_strconcat (type_name,
310 strcmp (widget_name, type_name) ? " (" : NULL,
311 widget_name, ")", NULL);
313 item = gtk_menu_item_new_with_label (item_label);
314 popup = g_object_get_data (G_OBJECT (self->widget), "popup");
318 popup = gtk_menu_new ();
319 g_object_set_data (G_OBJECT (self->widget), "popup", popup);
322 g_signal_connect (item, "activate", G_CALLBACK (item_activate_cb), widget);
323 gtk_menu_shell_append (GTK_MENU_SHELL (popup), item);
324 gtk_widget_show (item);
330 append_natural_size_box (TestCase *test,
336 GtkWidget *container = NULL;
337 GtkWidget *button, *label;
339 PangoEllipsizeMode ellipsize_mode;
342 for (i = 0; i < (table ? 9 : 6); ++i)
344 ellipsize_mode = ellipses ?
345 PANGO_ELLIPSIZE_START + i/(table ? 3 : 2) :
346 PANGO_ELLIPSIZE_NONE;
348 if (!i || (ellipses && 0 == i % (table ? 3 : 2)))
350 label = gtk_label_new (NULL);
352 switch(ellipsize_mode)
354 case PANGO_ELLIPSIZE_NONE:
355 gtk_label_set_markup (GTK_LABEL (label), "<b>No ellipses</b>");
357 case PANGO_ELLIPSIZE_START:
358 gtk_label_set_markup (GTK_LABEL (label), "<b>Ellipses at start</b>");
360 case PANGO_ELLIPSIZE_MIDDLE:
361 gtk_label_set_markup (GTK_LABEL (label), "<b>Ellipses in the middle</b>");
363 case PANGO_ELLIPSIZE_END:
364 gtk_label_set_markup (GTK_LABEL (label), "<b>Ellipses at end</b>");
370 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 1.0);
371 gtk_label_set_angle (GTK_LABEL (label), 90);
375 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
376 gtk_label_set_angle (GTK_LABEL (label), 0);
379 gtk_box_pack_start (GTK_BOX (parent), label, FALSE, TRUE, 0);
384 k = 1 + i / 3 + i % 3;
389 container = gtk_table_new (vertical ? k : 1,
390 vertical ? 1 : k, FALSE);
392 container = gtk_table_new (vertical ? k : 3,
393 vertical ? 3 : k, FALSE);
395 gtk_table_set_col_spacings (GTK_TABLE (container), 4);
396 gtk_table_set_row_spacings (GTK_TABLE (container), 4);
400 container = gtk_vbox_new (FALSE, 4);
402 container = gtk_hbox_new (FALSE, 4);
404 if (!gtk_widget_get_parent (container))
405 gtk_box_pack_start (GTK_BOX (parent), container, FALSE, TRUE, 0);
407 for (j = 0, l = i < 6 ? i / 3 : i - 6; j <= l; ++j)
409 label = gtk_label_new (NULL);
410 gtk_label_set_markup (GTK_LABEL (label), "<small>Small Button</small>");
411 gtk_label_set_angle (GTK_LABEL (label), vertical ? 90 : 0);
412 gtk_label_set_ellipsize (GTK_LABEL (label), ellipsize_mode);
414 button = gtk_button_new ();
415 set_widget_name (button, "small-%d-%d-%d", ellipses, i, j);
416 gtk_container_add (GTK_CONTAINER (button), label);
419 gtk_box_pack_start (GTK_BOX (container), button, FALSE, TRUE, 0);
421 gtk_table_attach (GTK_TABLE (container), button,
422 vertical ? 0 : j, vertical ? 1 : j + 1,
423 vertical ? j : 0, vertical ? j + 1 : 1,
424 GTK_FILL, GTK_FILL, 0, 0);
426 gtk_table_attach (GTK_TABLE (container), button,
427 vertical ? i - 6 : j,
428 vertical ? i - 5 : j < l ? j + 1 : 3,
429 vertical ? j : i - 6,
430 vertical ? (j < l ? j + 1 : 3) : i - 5,
431 GTK_FILL, GTK_FILL, 0, 0);
433 test_case_append_guide (test, button,
434 vertical ? GUIDE_EXTERIOUR_HORIZONTAL
435 : GUIDE_EXTERIOUR_VERTICAL,
436 6 == i ? 3 : 7 == i && j ? 4 : j);
439 for (j = 0, l = (i < 6 ? i % 3 : 1); j < l; ++j)
441 label = gtk_label_new (NULL);
442 gtk_label_set_markup (GTK_LABEL (label), "<small>Large Button</small>");
443 gtk_label_set_angle (GTK_LABEL (label), vertical ? 90 : 0);
445 button = gtk_button_new ();
446 set_widget_name (button, "large-%d-%d-%d", ellipses, i, j);
447 gtk_container_add (GTK_CONTAINER (button), label);
450 gtk_table_attach (GTK_TABLE (container), button,
451 vertical ? MAX (0, i - 6) : i/3 + j + 1,
452 vertical ? MAX (1, i - 5) : i/3 + j + 2,
453 vertical ? i/3 + j + 1 : MAX (0, i - 6),
454 vertical ? i/3 + j + 2 : MAX (1, i - 5),
455 vertical ? GTK_FILL : GTK_FILL | GTK_EXPAND,
456 vertical ? GTK_FILL | GTK_EXPAND : GTK_FILL,
459 gtk_box_pack_start (GTK_BOX (container), button, TRUE, TRUE, 0);
461 test_case_append_guide (test, button,
462 vertical ? GUIDE_EXTERIOUR_HORIZONTAL
463 : GUIDE_EXTERIOUR_VERTICAL,
464 i < 6 ? 5 + i + j : 12);
470 restore_paned (gpointer data)
477 paned = GTK_PANED (data);
478 hint = gtk_paned_get_child2 (paned);
479 gtk_widget_set_sensitive (hint, TRUE);
481 pos = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (paned), "initial-position"));
482 gtk_paned_set_position (paned, pos);
488 shrink_paned_timeout (gpointer data)
493 paned = GTK_PANED (data);
494 pos = gtk_paned_get_position (paned);
498 g_timeout_add (1000, restore_paned, paned);
502 gtk_paned_set_position (paned, pos - 5);
507 shrink_paned (GtkWidget *button,
513 paned = GTK_PANED (data);
514 hint = gtk_paned_get_child2 (paned);
515 gtk_widget_set_sensitive (hint, FALSE);
517 g_object_set_data (G_OBJECT (paned), "initial-position",
518 GINT_TO_POINTER (gtk_paned_get_position (paned)));
519 g_timeout_add (50, shrink_paned_timeout, paned);
523 natural_size_test_new (TestSuite *suite,
527 GtkWidget *box, *paned, *hint, *button;
533 detail = table ? "GtkTable, vertical" : "GtkVBox";
534 hint = gtk_alignment_new (0.5, 1.0, 1.0, 0.0);
535 box = gtk_hbox_new (FALSE, 6);
536 paned = gtk_vpaned_new ();
540 detail = table ? "GtkTable, horizontal" : "GtkHBox";
541 hint = gtk_alignment_new (1.0, 0.5, 0.0, 1.0);
542 box = gtk_vbox_new (FALSE, 6);
543 paned = gtk_hpaned_new ();
546 test = test_case_new (suite, "Natural Size", detail, paned);
547 gtk_container_set_border_width (GTK_CONTAINER (test->widget), 6);
549 gtk_container_set_border_width (GTK_CONTAINER (box), 6);
550 gtk_paned_pack1 (GTK_PANED (test->widget), box, TRUE, TRUE);
552 append_natural_size_box (test, box, vertical, table, FALSE);
553 append_natural_size_box (test, box, vertical, table, TRUE);
555 button = gtk_button_new_with_label ("Shrink to check ellipsing");
556 g_signal_connect (button, "clicked", G_CALLBACK (shrink_paned), test->widget);
559 gtk_label_set_angle (GTK_LABEL (GTK_BIN (button)->child), -90);
561 gtk_container_set_border_width (GTK_CONTAINER (hint), 6);
562 gtk_container_add (GTK_CONTAINER (hint), button);
563 gtk_paned_pack2 (GTK_PANED (test->widget), hint, FALSE, FALSE);
569 on_socket_realized (GtkWidget *widget,
572 gtk_socket_add_id (GTK_SOCKET (widget), GPOINTER_TO_INT (data));
576 on_xembed_socket_realized (GtkWidget *widget,
579 GdkNativeWindow plug_id = 0;
580 GError *error = NULL;
584 if (g_spawn_async_with_pipes (NULL, argv, NULL, 0,
586 NULL, &child_stdout, NULL,
593 len = read (child_stdout, buffer, sizeof (buffer) - 1);
594 close (child_stdout);
599 plug_id = atoi (buffer);
602 plug_str = g_strdup_printf ("plug-id=%d", plug_id);
603 g_print ("%s: %s\n", gtk_widget_get_name (widget), plug_str);
604 gtk_widget_set_tooltip_text (widget, plug_str);
609 GtkWidget *plug, *label;
610 gchar *error_message;
612 error_message = g_strdup_printf (
613 "Failed to create external plug:\n%s",
614 error ? error->message : "No details available.");
616 label = gtk_label_new (error_message);
617 g_warning (error_message);
619 g_free (error_message);
620 g_clear_error (&error);
622 if (argv[2] && g_str_equal (argv[2], "--vertical"))
623 gtk_label_set_angle (GTK_LABEL (label), 90);
625 plug = gtk_plug_new (0);
626 gtk_container_add (GTK_CONTAINER (plug), label);
627 gtk_widget_show_all (plug);
629 plug_id = gtk_plug_get_id (GTK_PLUG (plug));
632 gtk_socket_add_id (GTK_SOCKET (widget), plug_id);
636 natural_size_test_misc_create_child (TestCase *test,
642 const gchar *type_names[] =
644 "align", "socket-gtkplug", "socket-xembed",
645 "cell-view", "tree-view", "tree-view-scrolled",
648 const gchar *numbers[] =
650 "First", "Second", "Third", "Fourth", "Fifth",
651 "Sixth", "Seventh", "Eighth", "Nineth", NULL
654 GtkWidget *label, *child, *view, *align, *plug;
655 GdkNativeWindow plug_id;
657 GtkListStore *store = NULL;
658 GtkTreeViewColumn *column;
659 GtkCellRenderer *cell;
669 store = gtk_list_store_new (3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
671 for (i = 0; numbers[i] && (type > 4 || i < 2); ++i)
673 gchar *small = g_strdup_printf ("%s Small Cell", numbers[i]);
674 gchar *large = g_strdup_printf ("%s Large Cell", numbers[i]);
678 gtk_list_store_append (store, &iter);
679 gtk_list_store_set (store, &iter, 0, GTK_STOCK_ABOUT,
680 1, small, 2, large, -1);
687 for (i = 0; i < 2; ++i)
689 label = gtk_label_new ("Hello World");
691 gtk_label_set_ellipsize (GTK_LABEL (label),
692 i ? PANGO_ELLIPSIZE_END :
693 PANGO_ELLIPSIZE_NONE);
696 gtk_label_set_angle (GTK_LABEL (label), 90);
705 plug = gtk_plug_new (0);
706 plug_id = gtk_plug_get_id (GTK_PLUG (plug));
707 gtk_container_add (GTK_CONTAINER (plug), label);
708 gtk_widget_show_all (plug);
710 child = gtk_socket_new ();
712 g_signal_connect (child, "realize",
713 G_CALLBACK (on_socket_realized),
714 GINT_TO_POINTER (plug_id));
718 child = gtk_socket_new ();
720 argv = g_new0 (gchar*, 5);
724 argv[argc++] = "--action=create-plug";
727 argv[argc++] = "--vertical";
729 argv[argc++] = "--ellipsize";
731 g_signal_connect_data (child, "realize",
732 G_CALLBACK (on_xembed_socket_realized),
733 argv, (GClosureNotify) g_free, 0);
737 child = gtk_cell_view_new ();
739 if (gdk_color_parse ("#ffc", &color))
740 gtk_cell_view_set_background_color (GTK_CELL_VIEW (child), &color);
742 cell = gtk_cell_renderer_pixbuf_new ();
743 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (child), cell, FALSE);
744 gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (child), cell,
745 "stock-id", 0, NULL);
747 cell = gtk_cell_renderer_text_new ();
748 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (child), cell, FALSE);
749 gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (child), cell,
753 g_object_set (cell, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
755 cell = gtk_cell_renderer_text_new ();
756 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (child), cell, TRUE);
757 gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (child), cell,
760 gtk_cell_view_set_model (GTK_CELL_VIEW (child),
761 GTK_TREE_MODEL (store));
763 path = gtk_tree_path_new_from_indices (0, -1);
764 gtk_cell_view_set_displayed_row (GTK_CELL_VIEW (child), path);
765 gtk_tree_path_free (path);
771 view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
772 gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (view), FALSE);
774 cell = gtk_cell_renderer_pixbuf_new ();
775 column = gtk_tree_view_column_new_with_attributes (NULL, cell, "stock-id", 0, NULL);
776 gtk_tree_view_append_column (GTK_TREE_VIEW (view), column);
778 cell = gtk_cell_renderer_text_new ();
779 column = gtk_tree_view_column_new_with_attributes ("Bar", cell, "text", 1, NULL);
780 gtk_tree_view_append_column (GTK_TREE_VIEW (view), column);
783 g_object_set (cell, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
785 cell = gtk_cell_renderer_text_new ();
786 column = gtk_tree_view_column_new_with_attributes ("Foo", cell, "text", 2, NULL);
787 gtk_tree_view_append_column (GTK_TREE_VIEW (view), column);
791 child = gtk_scrolled_window_new (NULL, NULL);
792 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (child),
794 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (child),
797 gtk_container_add (GTK_CONTAINER (child), view);
808 align = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
809 gtk_box_pack_start (GTK_BOX (box), align, FALSE, TRUE, 0);
810 gtk_container_add (GTK_CONTAINER (align), child);
812 set_widget_name (child, "%s-%s-ellipsize-%s",
813 orientation ? "horizontal" : "vertical",
814 type_names[type], i ? "end" : "none");
816 test_case_append_guide (test, child,
817 orientation ? GUIDE_EXTERIOUR_VERTICAL
818 : GUIDE_EXTERIOUR_HORIZONTAL,
819 type < 3 ? orientation : type - 1);
824 natural_size_test_misc_new (TestSuite *suite,
827 const gchar *captions[] =
829 "<b>GtkAligment</b>",
830 "<b>GtkSocket with GtkPlug</b>",
831 "<b>GtkSocket with XEMBED</b>",
832 "<b>GtkCellView</b>",
833 "<b>GtkTreeView</b>",
834 "<b>GtkTreeView within GtkScrolledWindow</b>"
837 GtkWidget *box, *hpaned, *vpaned, *label;
838 gint orientation, type;
841 test = test_case_new (suite, "Natural Size", "Various Widgets",
842 gtk_vbox_new (FALSE, 6));
844 gtk_container_set_border_width (GTK_CONTAINER (test->widget), 6);
846 vpaned = NULL; /* silence the gcc */
848 for (orientation = 0; orientation < 2; ++orientation)
850 label = gtk_label_new ("Move the handle to test\n"
851 "natural size allocation");
852 gtk_misc_set_padding (GTK_MISC (label), 6, 6);
856 gtk_label_set_angle (GTK_LABEL (label), 90);
857 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
859 hpaned = gtk_hpaned_new ();
860 box = gtk_hbox_new (FALSE, 6);
862 gtk_box_pack_start (GTK_BOX (box), label, FALSE, TRUE, 0);
863 gtk_box_pack_start (GTK_BOX (box), gtk_vseparator_new (), FALSE, TRUE, 0);
864 gtk_box_pack_start (GTK_BOX (box), vpaned, TRUE, TRUE, 0);
866 gtk_paned_pack2 (GTK_PANED (hpaned), box, TRUE, FALSE);
868 box = gtk_vbox_new (FALSE, 6);
870 gtk_paned_pack1 (GTK_PANED (hpaned), box, TRUE, TRUE);
871 gtk_box_pack_start (GTK_BOX (test->widget), hpaned, TRUE, TRUE, 0);
875 gtk_misc_set_alignment (GTK_MISC (label), 0.5, 1.0);
877 vpaned = gtk_vpaned_new ();
878 box = gtk_hbox_new (FALSE, 6);
880 gtk_paned_pack1 (GTK_PANED (vpaned), box, TRUE, TRUE);
881 gtk_paned_pack2 (GTK_PANED (vpaned), label, FALSE, FALSE);
884 for (type = 0; type < (orientation ? 6 : 3); ++type)
886 label = gtk_label_new (NULL);
887 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
888 gtk_label_set_markup (GTK_LABEL (label), captions[type]);
889 gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_END);
890 gtk_box_pack_start (GTK_BOX (box), label, FALSE, TRUE, 0);
893 gtk_label_set_angle (GTK_LABEL (label), 90);
895 natural_size_test_misc_create_child (test, box, arg0, orientation, type);
903 size_for_allocation_test_new (TestSuite *suite,
907 GtkWidget *container, *child;
913 test = test_case_new (suite,
914 "Size for Allocation",
915 table ? "Height for Width, GtkTable"
916 : "Height for Width, GtkVBox",
921 container = gtk_table_new (4, 1, FALSE);
922 gtk_orientable_set_orientation (GTK_ORIENTABLE (container),
923 GTK_ORIENTATION_VERTICAL);
926 container = gtk_vbox_new (FALSE, 6);
928 child = gtk_label_new ("Move the handle to test\n"
929 "height-for-width requests");
931 gtk_label_set_angle (GTK_LABEL (child), 90);
935 test = test_case_new (suite,
936 "Size for Allocation",
937 table ? "Width for Height, GtkTable"
938 : "Width for Height, GtkHBox",
943 container = gtk_table_new (1, 4, FALSE);
944 gtk_orientable_set_orientation (GTK_ORIENTABLE (container),
945 GTK_ORIENTATION_HORIZONTAL);
948 container = gtk_hbox_new (FALSE, 6);
950 child = gtk_label_new ("Move the handle to test\n"
951 "width-for-height requests");
954 gtk_container_set_border_width (GTK_CONTAINER (test->widget), 6);
955 gtk_container_set_border_width (GTK_CONTAINER (container), 6);
956 gtk_misc_set_padding (GTK_MISC (child), 6, 6);
958 gtk_paned_pack1 (GTK_PANED (test->widget), container, TRUE, FALSE);
959 gtk_paned_pack2 (GTK_PANED (test->widget), child, FALSE, FALSE);
961 for (i = 0; i < 4; ++i)
965 child = gtk_label_new (lorem_ipsum);
966 gtk_label_set_line_wrap (GTK_LABEL (child), TRUE);
967 gtk_label_set_use_markup (GTK_LABEL (child), TRUE);
968 test_case_append_guide (test, child, GUIDE_EXTERIOUR_BOTH, -1);
969 test_case_append_guide (test, child, GUIDE_INTERIOUR_BOTH, -1);
972 gtk_box_pack_start (GTK_BOX (container), child, FALSE, TRUE, 0);
974 gtk_table_attach (GTK_TABLE (container), child, 0, 1, i, i + 1,
975 GTK_EXPAND|GTK_FILL, GTK_FILL, 0, 0);
977 gtk_table_attach (GTK_TABLE (container), child, i, i + 1, 0, 1,
978 GTK_FILL, GTK_EXPAND|GTK_FILL, 0, 0);
981 gtk_label_set_full_size (GTK_LABEL (child), TRUE);
984 gtk_label_set_angle (GTK_LABEL (child), vertical ? 180 : 270);
986 gtk_label_set_angle (GTK_LABEL (child), 90);
988 set_widget_name (child, "%s-label-and-%g-degree",
989 i > 0 ? "full-size" : "regular",
990 gtk_label_get_angle (GTK_LABEL (child)));
994 child = gtk_button_new ();
995 set_widget_name (child, "the-button");
996 gtk_container_add (GTK_CONTAINER (child),
997 gtk_image_new_from_stock (GTK_STOCK_DIALOG_INFO,
998 GTK_ICON_SIZE_DIALOG));
1001 gtk_box_pack_start (GTK_BOX (container), child, TRUE, TRUE, 0);
1003 gtk_table_attach (GTK_TABLE (container), child, 0, 1, i, i + 1,
1004 GTK_EXPAND|GTK_FILL, GTK_EXPAND|GTK_FILL, 0, 0);
1006 gtk_table_attach (GTK_TABLE (container), child, i, i + 1, 0, 1,
1007 GTK_EXPAND|GTK_FILL, GTK_EXPAND|GTK_FILL, 0, 0);
1015 baseline_test_new (TestSuite *suite)
1021 TestCase *test = test_case_new (suite,
1022 "Baseline Alignment", "Real-World Example",
1023 gtk_table_new (3, 3, FALSE));
1025 gtk_container_set_border_width (GTK_CONTAINER (test->widget), 12);
1026 gtk_table_set_col_spacings (GTK_TABLE (test->widget), 6);
1027 gtk_table_set_row_spacings (GTK_TABLE (test->widget), 6);
1029 child = gtk_entry_new ();
1030 gtk_entry_set_text (GTK_ENTRY (child), "Test...");
1031 test_case_append_guide (test, child, GUIDE_BASELINE, 0);
1032 gtk_table_attach (GTK_TABLE (test->widget), child, 1, 2, 0, 1,
1033 GTK_FILL | GTK_EXPAND, GTK_FILL, 0, 0);
1035 label = gtk_label_new_with_mnemonic ("_Title:");
1036 test_case_append_guide (test, label, GUIDE_BASELINE, 0);
1037 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
1038 gtk_label_set_mnemonic_widget (GTK_LABEL (label), child);
1039 gtk_table_attach (GTK_TABLE (test->widget), label, 0, 1, 0, 1,
1040 GTK_FILL, GTK_FILL, 0, 0);
1042 label = gtk_label_new_with_mnemonic ("Notice on\ntwo rows.");
1043 test_case_append_guide (test, label, GUIDE_BASELINE, 0);
1044 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.0);
1045 gtk_table_attach (GTK_TABLE (test->widget), label, 2, 3, 0, 2,
1046 GTK_FILL, GTK_FILL, 0, 0);
1048 child = gtk_font_button_new ();
1049 test_case_append_guide (test, child, GUIDE_BASELINE, 1);
1050 gtk_table_attach (GTK_TABLE (test->widget), child, 1, 2, 1, 2,
1051 GTK_FILL | GTK_EXPAND, GTK_FILL, 0, 0);
1053 label = gtk_label_new_with_mnemonic ("_Font:");
1054 test_case_append_guide (test, label, GUIDE_BASELINE, 1);
1055 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
1056 gtk_label_set_mnemonic_widget (GTK_LABEL (label), child);
1057 gtk_table_attach (GTK_TABLE (test->widget), label, 0, 1, 1, 2,
1058 GTK_FILL, GTK_FILL, 0, 0);
1060 view = gtk_text_view_new ();
1061 gtk_widget_set_size_request (view, 200, -1);
1062 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (view),
1064 test_case_append_guide (test, view, GUIDE_BASELINE, 2);
1065 gtk_text_buffer_set_text (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)),
1068 child = gtk_scrolled_window_new (NULL, NULL);
1069 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (child),
1070 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
1071 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (child),
1073 gtk_container_add (GTK_CONTAINER (child), view);
1075 gtk_table_attach (GTK_TABLE (test->widget), child, 1, 3, 2, 3,
1076 GTK_FILL | GTK_EXPAND,
1077 GTK_FILL | GTK_EXPAND,
1080 label = gtk_label_new_with_mnemonic ("_Comment:");
1081 test_case_append_guide (test, label, GUIDE_BASELINE, 2);
1082 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.0);
1083 gtk_label_set_mnemonic_widget (GTK_LABEL (label), child);
1084 gtk_table_attach (GTK_TABLE (test->widget), label, 0, 1, 2, 3,
1085 GTK_FILL, GTK_FILL, 0, 0);
1091 baseline_test_bin_new (TestSuite *suite)
1099 const GType types[] =
1101 GTK_TYPE_ALIGNMENT, GTK_TYPE_BUTTON,
1102 GTK_TYPE_EVENT_BOX, GTK_TYPE_FRAME,
1106 TestCase *test = test_case_new (suite,
1107 "Baseline Alignment", "Various GtkBins",
1108 gtk_alignment_new (0.5, 0.5, 0.0, 0.0));
1110 table = gtk_table_new (G_N_ELEMENTS (types) - 1,
1111 G_N_ELEMENTS (captions),
1114 gtk_container_set_border_width (GTK_CONTAINER (table), 12);
1115 gtk_table_set_col_spacings (GTK_TABLE (table), 6);
1116 gtk_table_set_row_spacings (GTK_TABLE (table), 6);
1117 gtk_container_add (GTK_CONTAINER (test->widget), table);
1119 for (i = 0; types[i]; ++i)
1121 label = gtk_label_new (g_type_name (types[i]));
1122 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
1124 gtk_table_attach (GTK_TABLE (table), label, 0, 1,
1125 i, i + 1, GTK_FILL, GTK_FILL, 0, 0);
1127 for (j = 0; captions[j]; ++j)
1129 bin = g_object_new (types[i], NULL);
1130 label = gtk_label_new (NULL);
1132 gtk_label_set_markup (GTK_LABEL (label), captions[j]);
1133 gtk_container_add (GTK_CONTAINER (bin), label);
1135 test_case_append_guide (test, bin, GUIDE_BASELINE, i);
1136 gtk_table_attach (GTK_TABLE (table), bin, j + 1, j + 2,
1137 i, i + 1, GTK_FILL, GTK_FILL, 0, 0);
1146 baseline_test_hbox_new (TestSuite *suite,
1156 const gchar *names[] =
1158 "default", "baseline", "baseline and bottom-padding",
1159 "baseline and top-padding", "baseline and border-width",
1163 TestCase *test = test_case_new (suite, "Baseline Alignment",
1164 buttons ? "GtkHBox and Buttons"
1165 : "GtkHBox and Labels",
1166 gtk_alignment_new (0.5, 0.5, 0.0, 0.0));
1168 table = gtk_table_new (G_N_ELEMENTS (names) - 1,
1169 G_N_ELEMENTS (captions),
1172 gtk_container_set_border_width (GTK_CONTAINER (table), 12);
1173 gtk_table_set_col_spacings (GTK_TABLE (table), 6);
1174 gtk_table_set_row_spacings (GTK_TABLE (table), 6);
1175 gtk_container_add (GTK_CONTAINER (test->widget), table);
1177 for (i = 0; names[i]; ++i)
1179 child = gtk_label_new (names[i]);
1180 gtk_misc_set_alignment (GTK_MISC (child), 0.0, 0.5);
1182 hbox = gtk_hbox_new (FALSE, 6);
1183 test_case_append_guide (test, hbox, GUIDE_EXTERIOUR_BOTH, -1);
1184 set_widget_name (hbox, "hbox-%s", names[i]);
1187 gtk_hbox_set_baseline_policy (GTK_HBOX (hbox), GTK_BASELINE_FIRST);
1189 gtk_table_attach (GTK_TABLE (table), child,
1191 GTK_FILL, GTK_FILL, 0, 0);
1192 gtk_table_attach (GTK_TABLE (table), hbox,
1193 1, G_N_ELEMENTS (captions), i, i + 1,
1194 GTK_FILL, GTK_FILL, 0, 0);
1196 for (j = i ? -3 : 0; captions[MAX (0, j)]; ++j)
1198 child = gtk_label_new (NULL);
1199 gtk_label_set_markup (GTK_LABEL (child), captions[MAX (0, j)]);
1203 bin = gtk_button_new ();
1204 gtk_container_add (GTK_CONTAINER (bin), child);
1208 test_case_append_guide (test, child, GUIDE_BASELINE, i);
1212 bin = gtk_alignment_new (0.5, 0.5, 0.0, (j + 3) * 0.5);
1214 set_widget_name (bin, "align-%s-%s-%d",
1215 buttons ? "button" : "label",
1216 names[i], (j + 3) * 50);
1221 gtk_alignment_set_padding (GTK_ALIGNMENT (bin), 0, 25, 0, 0);
1225 gtk_alignment_set_padding (GTK_ALIGNMENT (bin), 25, 0, 0, 0);
1229 gtk_container_set_border_width (GTK_CONTAINER (bin), 12);
1233 gtk_container_add (GTK_CONTAINER (bin), child);
1234 test_case_append_guide (test, bin, GUIDE_BASELINE, i);
1238 gtk_box_pack_start (GTK_BOX (hbox), child, FALSE, TRUE, 0);
1247 get_extends (GtkWidget *widget,
1248 GtkWidget *toplevel,
1249 GdkRectangle *extends)
1251 *extends = widget->allocation;
1254 gtk_widget_get_visible (widget) &&
1255 gtk_widget_translate_coordinates (widget, toplevel, 0, 0,
1256 &extends->x, &extends->y);
1260 get_interiour (GtkWidget *widget,
1261 GtkWidget *toplevel,
1262 GdkRectangle *extends)
1264 if (GTK_IS_LABEL (widget))
1266 PangoLayout *layout;
1270 label = GTK_LABEL (widget);
1271 layout = gtk_label_get_layout (label);
1272 pango_layout_get_pixel_extents (layout, NULL, &log);
1273 gtk_label_get_layout_offsets (label, &log.x, &log.y);
1275 log.x -= toplevel->allocation.x;
1276 log.y -= toplevel->allocation.y;
1278 g_assert (sizeof log == sizeof *extends);
1279 memcpy (extends, &log, sizeof *extends);
1286 get_baseline_of_layout (PangoLayout *layout)
1288 PangoLayoutLine *line;
1291 line = pango_layout_get_line_readonly (layout, 0);
1292 pango_layout_line_get_pixel_extents (line, NULL, &log);
1293 return PANGO_ASCENT (log);
1297 get_baselines_of_text_view (GtkTextView *view, gint **baselines)
1299 GtkTextBuffer *buffer = gtk_text_view_get_buffer (view);
1300 GtkTextAttributes *attrs = gtk_text_view_get_default_attributes (view);
1301 PangoContext *context = gtk_widget_get_pango_context (GTK_WIDGET (view));
1302 PangoLayout *layout = pango_layout_new (context);
1304 GtkTextIter start, end;
1305 GdkRectangle bounds;
1308 gtk_text_buffer_get_start_iter (buffer, &start);
1309 gtk_text_iter_get_attributes (&start, attrs);
1312 gtk_text_iter_forward_to_line_end (&end);
1313 text = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
1314 gtk_text_view_get_iter_location (view, &start, &bounds);
1316 pango_layout_set_width (layout, PANGO_SCALE *
1317 GTK_WIDGET (view)->allocation.width);
1318 pango_layout_set_font_description (layout, attrs->font);
1319 pango_layout_set_wrap (layout, PANGO_WRAP_WORD);
1320 pango_layout_set_text (layout, text, -1);
1322 gtk_text_view_buffer_to_window_coords (view, GTK_TEXT_WINDOW_TEXT,
1323 0, bounds.y, NULL, &bounds.y);
1324 bounds.y += get_baseline_of_layout (layout);
1326 gtk_text_attributes_unref (attrs);
1327 g_object_unref (layout);
1330 *baselines = g_new(gint, 1);
1331 *baselines[0] = bounds.y;
1337 get_baselines (GtkWidget *widget, gint **baselines)
1340 if (GTK_IS_EXTENDED_LAYOUT (widget) &&
1341 GTK_EXTENDED_LAYOUT_HAS_BASELINES (widget))
1342 return gtk_extended_layout_get_baselines (GTK_EXTENDED_LAYOUT (widget), baselines);
1344 if (GTK_IS_TEXT_VIEW (widget))
1345 return get_baselines_of_text_view (GTK_TEXT_VIEW (widget), baselines);
1351 draw_baselines (GdkDrawable *drawable,
1353 GtkWidget *toplevel,
1354 GdkRectangle *extends,
1357 const gint x0 = toplevel->allocation.x;
1358 const gint y0 = toplevel->allocation.y;
1359 const gint cx = toplevel->allocation.width;
1361 const gint xa = x0 + extends->x;
1362 const gint xe = xa + extends->width - 1;
1363 const gint ya = y0 + extends->y + baseline;
1365 gdk_draw_line (drawable, gc, xa, ya - 5, xa, ya + 2);
1366 gdk_draw_line (drawable, gc, xa - 5, ya, xe + 5, ya);
1367 gdk_draw_line (drawable, gc, xe, ya - 5, xe, ya + 2);
1369 gdk_gc_set_line_attributes (gc, 1, GDK_LINE_ON_OFF_DASH,
1370 GDK_CAP_NOT_LAST, GDK_JOIN_MITER);
1372 gdk_gc_set_dashes (gc, x0 % (dashes[0] + dashes[1]), dashes, 2);
1373 gdk_draw_line (drawable, gc, x0, ya, xa - 5, ya);
1375 gdk_gc_set_dashes (gc, (xe + 2) % (dashes[0] + dashes[1]), dashes, 2);
1376 gdk_draw_line (drawable, gc, xe + 5, ya, x0 + cx - 1, ya);
1378 gdk_gc_set_line_attributes (gc, 1, GDK_LINE_SOLID,
1379 GDK_CAP_NOT_LAST, GDK_JOIN_MITER);
1383 draw_extends (GdkDrawable *drawable,
1385 GtkWidget *toplevel,
1386 GdkRectangle *extends)
1388 const gint x0 = toplevel->allocation.x;
1389 const gint y0 = toplevel->allocation.y;
1390 const gint cx = toplevel->allocation.width;
1391 const gint cy = toplevel->allocation.height;
1393 const gint xa = x0 + extends->x;
1394 const gint xe = xa + extends->width - 1;
1396 const gint ya = y0 + extends->y;
1397 const gint ye = ya + extends->height - 1;
1399 gdk_draw_line (drawable, gc, xa, y0, xa, y0 + cy - 1);
1400 gdk_draw_line (drawable, gc, xe, y0, xe, y0 + cy - 1);
1401 gdk_draw_line (drawable, gc, x0, ya, x0 + cx - 1, ya);
1402 gdk_draw_line (drawable, gc, x0, ye, x0 + cx - 1, ye);
1406 test_case_eval_guide (const TestCase *self,
1408 GdkRectangle *extends,
1411 gint num_baselines = -1;
1413 if (get_extends (guide->widget, self->widget, extends))
1417 switch (guide->type)
1419 case GUIDE_BASELINE:
1420 num_baselines = get_baselines (guide->widget, baselines);
1423 case GUIDE_INTERIOUR_BOTH:
1424 case GUIDE_INTERIOUR_VERTICAL:
1425 case GUIDE_INTERIOUR_HORIZONTAL:
1426 get_interiour (guide->widget, self->widget, extends);
1430 case GUIDE_EXTERIOUR_BOTH:
1431 case GUIDE_EXTERIOUR_VERTICAL:
1432 case GUIDE_EXTERIOUR_HORIZONTAL:
1438 return num_baselines;
1442 guide_is_compatible (const Guide *self,
1447 case GUIDE_BASELINE:
1449 GUIDE_BASELINE == other->type;
1451 case GUIDE_INTERIOUR_BOTH:
1452 case GUIDE_EXTERIOUR_BOTH:
1454 GUIDE_INTERIOUR_BOTH == other->type ||
1455 GUIDE_EXTERIOUR_BOTH == other->type;
1457 case GUIDE_INTERIOUR_VERTICAL:
1458 case GUIDE_EXTERIOUR_VERTICAL:
1460 GUIDE_INTERIOUR_VERTICAL == other->type ||
1461 GUIDE_EXTERIOUR_VERTICAL == other->type;
1463 case GUIDE_INTERIOUR_HORIZONTAL:
1464 case GUIDE_EXTERIOUR_HORIZONTAL:
1466 GUIDE_INTERIOUR_HORIZONTAL == other->type ||
1467 GUIDE_EXTERIOUR_HORIZONTAL == other->type;
1470 g_return_val_if_reached (FALSE);
1474 test_case_compare_guides (const TestCase *self,
1475 const Guide *guide1,
1476 const Guide *guide2)
1478 gint *baselines1 = NULL, *baselines2 = NULL;
1479 GdkRectangle extends1, extends2;
1480 gboolean equal = FALSE;
1482 if (guide_is_compatible (guide1, guide2) &&
1483 test_case_eval_guide (self, guide1, &extends1, &baselines1) >= 0 &&
1484 test_case_eval_guide (self, guide2, &extends2, &baselines2) >= 0)
1486 switch (guide1->type)
1488 case GUIDE_BASELINE:
1490 IS_VALID_BASELINE (*baselines1) &&
1491 IS_VALID_BASELINE (*baselines2) &&
1492 extends1.y + *baselines1 == extends2.y + *baselines2;
1495 case GUIDE_INTERIOUR_HORIZONTAL:
1496 case GUIDE_EXTERIOUR_HORIZONTAL:
1498 extends1.height == extends2.height &&
1499 extends1.y == extends2.y;
1502 case GUIDE_INTERIOUR_VERTICAL:
1503 case GUIDE_EXTERIOUR_VERTICAL:
1505 extends1.width == extends2.width &&
1506 extends1.x == extends2.x;
1509 case GUIDE_INTERIOUR_BOTH:
1510 case GUIDE_EXTERIOUR_BOTH:
1511 equal = !memcpy (&extends1, &extends2, sizeof extends1);
1517 g_free (baselines1);
1518 g_free (baselines2);
1524 guide_type_get_color (GuideType type,
1525 gboolean is_current)
1529 case GUIDE_BASELINE: return is_current ? "#f00" : "#00f";
1530 default: return is_current ? "#000" : "#fff";
1535 draw_guides (gpointer data)
1537 TestCase *test = data;
1538 GdkDrawable *drawable;
1545 gboolean show_baselines;
1546 gboolean show_interiour;
1547 gboolean show_exteriour;
1549 values.subwindow_mode = GDK_INCLUDE_INFERIORS;
1550 drawable = test->widget->window;
1552 gc = gdk_gc_new_with_values (drawable, &values,
1555 gdk_gc_set_tile (gc, test->suite->tile);
1558 test->suite->baselines && gtk_toggle_button_get_active (
1559 GTK_TOGGLE_BUTTON (test->suite->baselines));
1561 test->suite->interiour && gtk_toggle_button_get_active (
1562 GTK_TOGGLE_BUTTON (test->suite->interiour));;
1564 test->suite->exteriour && gtk_toggle_button_get_active (
1565 GTK_TOGGLE_BUTTON (test->suite->exteriour));;
1567 for (iteration = 0; iteration < 3; ++iteration)
1569 for (iter = test->guides; iter; iter = iter->next)
1571 const Guide *guide = iter->data;
1572 gboolean is_current = (guide->widget == test->suite->current);
1573 GdkRectangle extends;
1578 if (!is_current != !iteration)
1583 if (test->suite->timestamp >= 3)
1588 gdk_gc_set_fill (gc, GDK_TILED);
1589 gdk_gc_set_function (gc, GDK_OR);
1591 gdk_draw_rectangle (drawable, gc, TRUE,
1592 guide->widget->allocation.x,
1593 guide->widget->allocation.y,
1594 guide->widget->allocation.width,
1595 guide->widget->allocation.height);
1597 gdk_gc_set_function (gc, GDK_COPY);
1598 gdk_gc_set_fill (gc, GDK_SOLID);
1604 gdk_color_parse (guide_type_get_color (guide->type, is_current),
1605 &values.foreground);
1607 gdk_gc_set_rgb_fg_color (gc, &values.foreground);
1609 num_baselines = test_case_eval_guide (test, guide, &extends, &baselines);
1611 if (num_baselines > 0)
1613 g_assert (NULL != baselines);
1616 for (i = 0; i < num_baselines; ++i)
1617 draw_baselines (drawable, gc, test->widget, &extends, baselines[i]);
1619 else if (num_baselines > -1)
1621 if ((show_interiour && (
1622 guide->type == GUIDE_INTERIOUR_VERTICAL ||
1623 guide->type == GUIDE_INTERIOUR_HORIZONTAL ||
1624 guide->type == GUIDE_INTERIOUR_BOTH)) ||
1625 (show_exteriour && (
1626 guide->type == GUIDE_EXTERIOUR_VERTICAL ||
1627 guide->type == GUIDE_EXTERIOUR_HORIZONTAL ||
1628 guide->type == GUIDE_EXTERIOUR_BOTH)))
1629 draw_extends (drawable, gc, test->widget, &extends);
1636 g_object_unref (gc);
1643 expose_cb (GtkWidget *widget,
1644 GdkEventExpose *event,
1647 TestCase *test = data;
1649 if (0 == test->idle)
1651 if (widget != test->widget)
1652 gtk_widget_queue_draw (test->widget);
1654 test->idle = g_idle_add (draw_guides, test);
1661 realize_cb (GtkWidget *widget,
1664 TestCase *test = data;
1666 if (widget->window != test->widget->window)
1667 g_signal_connect_after (widget, "expose-event",
1668 G_CALLBACK (expose_cb), test);
1672 attach_sub_windows (GtkWidget *widget,
1675 g_signal_connect_after (widget, "realize", G_CALLBACK (realize_cb), data);
1677 if (GTK_IS_CONTAINER (widget))
1678 gtk_container_forall (GTK_CONTAINER (widget), attach_sub_windows, data);
1682 test_suite_insert_page (TestSuite *self,
1687 GtkTreeModel *model = GTK_TREE_MODEL (self->tests);
1688 TestCase *prev = NULL;
1692 if (!widget && test)
1693 widget = test->widget;
1695 g_return_if_fail (GTK_IS_WIDGET (widget));
1697 n_rows = gtk_tree_model_iter_n_children (model, NULL);
1699 gtk_notebook_insert_page (GTK_NOTEBOOK (self->notebook),
1700 widget, NULL, self->n_test_cases);
1702 gtk_list_store_insert (self->tests, &iter, n_rows);
1704 gtk_list_store_set (self->tests, &iter,
1705 TEST_COLUMN_LABEL, label,
1706 TEST_COLUMN_SELECTED, NULL != test,
1707 TEST_COLUMN_HAS_TEST_CASE, NULL != test,
1708 TEST_COLUMN_PAGE_INDEX, self->n_test_cases,
1709 TEST_COLUMN_TEST_CASE, test,
1712 for (i = n_rows - 1; i >= 0 && NULL == prev &&
1713 gtk_tree_model_iter_nth_child (model, &iter, NULL, i);
1715 gtk_tree_model_get (GTK_TREE_MODEL (self->tests), &iter,
1716 TEST_COLUMN_TEST_CASE, &prev,
1719 if (NULL == test || (prev && strcmp (test->name, prev->name)))
1721 gtk_list_store_insert (self->tests, &iter, n_rows);
1722 gtk_list_store_set (self->tests, &iter,
1723 TEST_COLUMN_HAS_TEST_CASE, FALSE,
1724 TEST_COLUMN_PAGE_INDEX, -1,
1729 ++self->n_test_cases;
1733 test_suite_append (TestSuite *self,
1736 GString *markup = g_string_new (test->name);
1738 g_string_printf (markup, "<b>%s</b>", test->name);
1741 g_string_append_printf (markup, "\n<small>%s</small>", test->detail);
1743 test_suite_insert_page (self, test, NULL, markup->str);
1744 g_string_free (markup, TRUE);
1746 g_signal_connect_after (test->widget, "expose-event",
1747 G_CALLBACK (expose_cb), test);
1748 g_signal_connect_after (test->widget, "realize",
1749 G_CALLBACK (realize_cb), test);
1750 g_object_set_data_full (G_OBJECT(test->widget),
1751 "test-case", test, g_free);
1753 gtk_container_forall (GTK_CONTAINER (test->widget),
1754 attach_sub_windows, test);
1758 realize_notebook_cb (GtkWidget *widget,
1761 TestSuite *suite = data;
1764 gdk_pixmap_colormap_create_from_xpm_d (
1765 suite->notebook->window, NULL, NULL, NULL,
1770 test_suite_free (TestSuite* self)
1772 g_object_unref (self->tile);
1777 test_suite_start (TestSuite *self)
1779 if (0 == self->level++)
1781 g_print ("\033[1mStarting test suite.\033[0m\n");
1782 gtk_tree_store_clear (self->results);
1787 test_suite_stop (TestSuite *self)
1789 if (0 == --self->level)
1791 gtk_notebook_set_current_page (GTK_NOTEBOOK (self->notebook),
1792 self->n_test_cases);
1793 g_print ("\033[1mTest suite stopped.\033[0m\n");
1798 test_result_to_string (TestResult result)
1802 case TEST_RESULT_NONE: return NULL;
1803 case TEST_RESULT_SUCCESS: return "SUCCESS";
1804 case TEST_RESULT_FAILURE: return "FAILURE";
1807 g_return_val_if_reached (NULL);
1811 test_result_to_icon (TestResult result)
1815 case TEST_RESULT_NONE: return GTK_STOCK_EXECUTE;
1816 case TEST_RESULT_SUCCESS: return GTK_STOCK_OK;
1817 case TEST_RESULT_FAILURE: return GTK_STOCK_DIALOG_ERROR;
1820 g_return_val_if_reached (NULL);
1824 test_suite_report (TestSuite *self,
1825 const gchar *message,
1829 const gchar *text = test_result_to_string (result);
1830 const gchar *icon = test_result_to_icon (result);
1836 PangoWeight weight = PANGO_WEIGHT_NORMAL;
1839 if (TEST_RESULT_NONE != result)
1841 g_print (" - %s: %s\n", message, text);
1842 gtk_tree_store_append (self->results, &iter, &self->parent);
1846 g_print ("\033[1mTesting: %s\033[0m\n", message);
1847 gtk_tree_store_append (self->results, &self->parent, NULL);
1848 weight = PANGO_WEIGHT_BOLD;
1849 iter = self->parent;
1854 if (gtk_tree_store_iter_depth (self->results, &self->parent) < 1 ||
1855 !gtk_tree_model_iter_parent (GTK_TREE_MODEL (self->results), &iter, &self->parent))
1856 iter = self->parent;
1858 g_print (" * %s\n", message);
1859 gtk_tree_store_append (self->results, &self->parent, &iter);
1860 iter = self->parent;
1863 gtk_tree_store_set (self->results, &iter,
1864 RESULT_COLUMN_MESSAGE, message,
1865 RESULT_COLUMN_WEIGHT, weight,
1866 RESULT_COLUMN_RESULT, text,
1867 RESULT_COLUMN_ICON, icon,
1870 if (TEST_RESULT_FAILURE == result)
1872 path = gtk_tree_model_get_path (GTK_TREE_MODEL (self->results), &iter);
1873 gtk_tree_view_expand_to_path (GTK_TREE_VIEW (self->results_view), path);
1874 gtk_tree_path_free (path);
1879 if (-1 == group && gtk_tree_model_iter_parent (
1880 GTK_TREE_MODEL (self->results), &iter, &self->parent))
1881 self->parent = iter;
1883 gtk_tree_store_set (self->results, &self->parent,
1884 RESULT_COLUMN_RESULT, text,
1885 RESULT_COLUMN_ICON, icon,
1891 test_suite_run (TestSuite *self,
1894 GtkNotebook *notebook;
1898 notebook = GTK_NOTEBOOK (self->notebook);
1901 index = gtk_notebook_get_current_page (notebook);
1903 page = gtk_notebook_get_nth_page (notebook, index);
1904 test = g_object_get_data (G_OBJECT (page), "test-case");
1908 TestResult test_result = TEST_RESULT_SUCCESS;
1909 gint last_group = -1;
1914 message = test->detail ?
1915 g_strdup_printf ("%s (%s)", test->name, test->detail) :
1916 g_strdup (test->name);
1918 test_suite_start (self);
1919 test_suite_report (self, message, -1, TEST_RESULT_NONE);
1923 for (oiter = test->guides; oiter; oiter = oiter->next)
1924 last_group = MAX (last_group, ((const Guide*)oiter->data)->group);
1926 for (group = 0; group <= last_group; ++group)
1928 const Guide *oguide;
1930 for (o = 0, oiter = test->guides; oiter; ++o, oiter = oiter->next)
1932 oguide = oiter->data;
1934 if (oguide->group == group)
1940 TestResult group_result = TEST_RESULT_SUCCESS;
1941 const gchar *widget_name;
1942 const gchar *type_name;
1947 widget_name = gtk_widget_get_name (oguide->widget);
1948 type_name = G_OBJECT_TYPE_NAME (oguide->widget);
1950 message = g_strdup_printf (
1951 "Group %d, Guide %d (%s%s%s)",
1952 oguide->group, o, type_name,
1953 strcmp (type_name, widget_name) ? ": " : "",
1954 strcmp (type_name, widget_name) ? widget_name : "");
1956 test_suite_report (self, message, oguide->group, TEST_RESULT_NONE);
1959 for(i = 0, iiter = test->guides; iiter; ++i, iiter = iiter->next)
1961 const Guide *iguide = iiter->data;
1963 if (iguide->group == oguide->group)
1965 widget_name = gtk_widget_get_name (iguide->widget);
1966 type_name = G_OBJECT_TYPE_NAME (iguide->widget);
1968 message = g_strdup_printf (
1969 "Guide %d (%s%s%s)", i, type_name,
1970 strcmp (type_name, widget_name) ? ": " : "",
1971 strcmp (type_name, widget_name) ? widget_name : "");
1973 if (test_case_compare_guides (test, oguide, iguide))
1975 test_suite_report (self, message, oguide->group, TEST_RESULT_SUCCESS);
1979 test_suite_report (self, message, oguide->group, TEST_RESULT_FAILURE);
1980 group_result = TEST_RESULT_FAILURE;
1981 test_result = TEST_RESULT_FAILURE;
1988 test_suite_report (self, NULL, oguide->group, group_result);
1992 test_suite_report (self, NULL, -1, test_result);
1993 test_suite_stop (self);
1998 test_current_cb (GtkWidget *widget,
2001 TestSuite *suite = data;
2002 test_suite_run (suite, -1);
2006 test_suite_show_and_run_test (TestSuite *self,
2009 GTimer *timer = g_timer_new ();
2011 gtk_notebook_set_current_page (GTK_NOTEBOOK (self->notebook), page);
2012 g_timer_start (timer);
2014 while (g_timer_elapsed (timer, NULL) < 0.3 &&
2015 !gtk_main_iteration_do (FALSE))
2017 if (!gtk_events_pending ())
2021 test_suite_run (self, -1);
2022 g_timer_destroy (timer);
2026 test_selected_cb (GtkWidget *widget,
2029 TestSuite *suite = data;
2030 GtkTreeModel *model;
2033 model = GTK_TREE_MODEL (suite->tests);
2034 test_suite_start (suite);
2036 if (gtk_tree_model_get_iter_first (model, &iter))
2040 gboolean selected = FALSE;
2041 gint page_index = -1;
2043 gtk_tree_model_get (model, &iter,
2044 TEST_COLUMN_SELECTED, &selected,
2045 TEST_COLUMN_PAGE_INDEX, &page_index,
2048 if (page_index >= 0 && selected)
2049 test_suite_show_and_run_test (suite, page_index);
2051 while (gtk_tree_model_iter_next (model, &iter));
2054 test_suite_stop (suite);
2058 test_all_cb (GtkWidget *widget,
2061 TestSuite *suite = data;
2064 test_suite_start (suite);
2066 for (i = 0; i < suite->n_test_cases; ++i)
2067 test_suite_show_and_run_test (suite, i);
2069 test_suite_stop (suite);
2073 switch_page_cb (GtkNotebook *notebook,
2074 GtkNotebookPage *page,
2078 TestSuite *suite = data;
2079 GtkTreeModel *model;
2083 gtk_widget_set_sensitive (suite->test_current_button,
2084 index < suite->n_test_cases);
2086 model = GTK_TREE_MODEL (suite->tests);
2088 if (gtk_tree_model_get_iter_first (model, &iter))
2092 gtk_tree_model_get (model, &iter,
2093 TEST_COLUMN_PAGE_INDEX, &page_index,
2096 if (page_index == index)
2098 gtk_tree_selection_select_iter (suite->selection, &iter);
2102 while (gtk_tree_model_iter_next (model, &iter));
2107 find_widget_at_position (GtkWidget *widget,
2111 if (x < 0 || x >= widget->allocation.width ||
2112 y < 0 || y >= widget->allocation.height)
2115 if (GTK_IS_CONTAINER (widget))
2123 children = gtk_container_get_children (GTK_CONTAINER (widget));
2125 for (iter = children; iter; iter = iter->next)
2127 gtk_widget_translate_coordinates (widget, iter->data, x, y, &rx, &ry);
2128 child = find_widget_at_position (iter->data, rx, ry);
2137 g_list_free (children);
2144 queue_redraw (GtkWidget *page,
2149 gtk_widget_translate_coordinates (child, page, 0, 0, &x, &y);
2151 gtk_widget_queue_draw_area (page,
2153 page->allocation.y + y,
2154 page->allocation.width,
2155 child->allocation.height);
2156 gtk_widget_queue_draw_area (page,
2157 page->allocation.x + x,
2159 child->allocation.width,
2160 page->allocation.height);
2164 watch_pointer_cb (gpointer data)
2166 TestSuite *suite = data;
2167 GtkWidget *prev = suite->current;
2168 TestCase *test = NULL;
2175 i = gtk_notebook_get_current_page (GTK_NOTEBOOK (suite->notebook));
2176 page = gtk_notebook_get_nth_page (GTK_NOTEBOOK (suite->notebook), i);
2178 gtk_widget_get_pointer (page, &x, &y);
2179 child = find_widget_at_position (page, x, y);
2183 test = g_object_get_data (G_OBJECT(child), "test-case");
2188 child = gtk_widget_get_parent (child);
2191 dirty = suite->current && !(suite->timestamp % 3);
2192 suite->timestamp = (suite->timestamp + 1) % 6;
2196 dirty = (NULL != suite->current);
2199 gtk_label_set_text (GTK_LABEL (suite->statusbar),
2200 "No widget selected.\n");
2202 suite->current = NULL;
2204 else if (child != suite->hover)
2206 if (child != suite->current)
2207 update_status (suite, child);
2209 suite->current = child;
2210 suite->hover = child;
2218 if (prev && prev != suite->current)
2219 queue_redraw (page, prev);
2221 queue_redraw (page, suite->current);
2225 gtk_widget_queue_draw (page);
2233 button_press_event_cb (GtkWidget *widget,
2234 GdkEventButton *event,
2237 TestSuite *suite = data;
2238 GtkWidget *popup = NULL;
2242 if (3 != event->button)
2245 i = gtk_notebook_get_current_page (GTK_NOTEBOOK (suite->notebook));
2246 page = gtk_notebook_get_nth_page (GTK_NOTEBOOK (suite->notebook), i);
2247 popup = g_object_get_data (G_OBJECT (page), "popup");
2249 gtk_menu_popup (GTK_MENU (popup),
2250 NULL, NULL, NULL, NULL,
2251 event->button, event->time);
2257 test_suite_setup_results_page (TestSuite *self)
2259 GtkTreeViewColumn *column;
2260 GtkCellRenderer *cell;
2261 GtkWidget *scroller;
2263 self->results = gtk_tree_store_new (RESULT_COLUNN_COUNT,
2264 G_TYPE_STRING, PANGO_TYPE_WEIGHT,
2265 G_TYPE_STRING, G_TYPE_STRING);
2267 self->results_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (self->results));
2268 gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (self->results_view), FALSE);
2270 column = gtk_tree_view_column_new ();
2271 gtk_tree_view_column_set_expand (column, TRUE);
2272 gtk_tree_view_append_column (GTK_TREE_VIEW (self->results_view), column);
2274 cell = gtk_cell_renderer_pixbuf_new ();
2275 gtk_tree_view_column_pack_start (column, cell, FALSE);
2276 gtk_tree_view_column_set_attributes (column, cell,
2277 "icon-name", RESULT_COLUMN_ICON, NULL);
2279 cell = gtk_cell_renderer_text_new ();
2280 gtk_tree_view_column_pack_start (column, cell, TRUE);
2281 gtk_tree_view_column_set_attributes (column, cell,
2282 "text", RESULT_COLUMN_MESSAGE,
2283 "weight", RESULT_COLUMN_WEIGHT, NULL);
2285 column = gtk_tree_view_column_new ();
2286 gtk_tree_view_column_set_expand (column, FALSE);
2287 gtk_tree_view_append_column (GTK_TREE_VIEW (self->results_view), column);
2289 cell = gtk_cell_renderer_text_new ();
2290 gtk_tree_view_column_pack_start (column, cell, TRUE);
2291 gtk_tree_view_column_set_attributes (column, cell,
2292 "text", RESULT_COLUMN_RESULT, NULL);
2294 scroller = gtk_scrolled_window_new (NULL, NULL);
2295 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroller),
2296 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
2297 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroller),
2299 gtk_container_set_border_width (GTK_CONTAINER (scroller), 12);
2300 gtk_container_add (GTK_CONTAINER (scroller), self->results_view);
2302 test_suite_insert_page (self, NULL, scroller, "<b>Test Results</b>");
2304 g_signal_connect (self->notebook, "realize",
2305 G_CALLBACK (realize_notebook_cb), self);
2309 tests_is_separator (GtkTreeModel *model,
2315 gtk_tree_model_get (model, iter, TEST_COLUMN_LABEL, &label, -1);
2318 return (NULL == label);
2322 test_case_toggled (GtkCellRendererToggle *cell,
2328 if (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (data), &iter, path))
2329 gtk_list_store_set (GTK_LIST_STORE (data), &iter, TEST_COLUMN_SELECTED,
2330 !gtk_cell_renderer_toggle_get_active (cell),
2335 selection_changed (GtkTreeSelection *selection,
2338 TestSuite *suite = data;
2339 GtkTreeModel *model;
2343 if (gtk_tree_selection_get_selected (selection, &model, &iter))
2345 gtk_tree_model_get (model, &iter,
2346 TEST_COLUMN_PAGE_INDEX, &page_index,
2349 if (page_index >= 0)
2350 gtk_notebook_set_current_page (GTK_NOTEBOOK (suite->notebook),
2356 test_suite_setup_ui (TestSuite *self)
2358 GtkWidget *table, *actions, *button, *align;
2359 GtkWidget *view, *scrolled;
2361 GtkTreeViewColumn *column;
2362 GtkCellRenderer *cell;
2364 self->tests = gtk_list_store_new (TEST_COLUMN_COUNT,
2365 G_TYPE_STRING, G_TYPE_BOOLEAN,
2366 G_TYPE_POINTER, G_TYPE_BOOLEAN,
2369 view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (self->tests));
2370 gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (view), FALSE);
2371 gtk_tree_view_set_row_separator_func (GTK_TREE_VIEW (view), tests_is_separator, NULL, NULL);
2373 self->selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
2374 gtk_tree_selection_set_mode (self->selection, GTK_SELECTION_BROWSE);
2376 g_signal_connect (self->selection, "changed", G_CALLBACK (selection_changed), self);
2378 column = gtk_tree_view_column_new ();
2379 cell = gtk_cell_renderer_toggle_new ();
2380 gtk_tree_view_append_column (GTK_TREE_VIEW (view), column);
2381 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (column), cell, FALSE);
2382 gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (column), cell,
2383 "active", TEST_COLUMN_SELECTED,
2384 "activatable", TEST_COLUMN_HAS_TEST_CASE,
2385 "visible", TEST_COLUMN_HAS_TEST_CASE,
2388 g_signal_connect (cell, "toggled", G_CALLBACK (test_case_toggled), self->tests);
2390 column = gtk_tree_view_column_new ();
2391 cell = gtk_cell_renderer_text_new ();
2392 gtk_tree_view_append_column (GTK_TREE_VIEW (view), column);
2393 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (column), cell, TRUE);
2394 gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (column), cell,
2395 "markup", TEST_COLUMN_LABEL, NULL);
2397 scrolled = gtk_scrolled_window_new (NULL, NULL);
2398 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled),
2400 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled),
2401 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
2402 gtk_container_add (GTK_CONTAINER (scrolled), view);
2404 self->notebook = gtk_notebook_new ();
2405 gtk_notebook_set_show_tabs (GTK_NOTEBOOK (self->notebook), FALSE);
2407 actions = gtk_hbox_new (TRUE, 12);
2409 align = gtk_alignment_new (1.0, 0.5, 0.0, 0.0);
2410 gtk_container_add (GTK_CONTAINER (align), actions);
2412 button = gtk_button_new_with_mnemonic ("Test _Current Page");
2413 g_signal_connect (button, "clicked", G_CALLBACK (test_current_cb), self);
2414 gtk_box_pack_start (GTK_BOX (actions), button, FALSE, TRUE, 0);
2416 self->test_current_button = button;
2417 g_signal_connect (self->notebook, "switch-page", G_CALLBACK (switch_page_cb), self);
2419 button = gtk_button_new_with_mnemonic ("Test _Selected Pages");
2420 g_signal_connect (button, "clicked", G_CALLBACK (test_selected_cb), self);
2421 gtk_box_pack_start (GTK_BOX (actions), button, FALSE, TRUE, 0);
2423 button = gtk_button_new_with_mnemonic ("Test _All Pages");
2424 g_signal_connect (button, "clicked", G_CALLBACK (test_all_cb), self);
2425 gtk_box_pack_start (GTK_BOX (actions), button, FALSE, TRUE, 0);
2427 actions = gtk_hbox_new (FALSE, 12);
2428 gtk_box_pack_end (GTK_BOX (actions), align, TRUE, TRUE, 0);
2430 gtk_box_pack_start (GTK_BOX (actions),
2431 gtk_label_new ("Guides:"),
2434 self->baselines = gtk_check_button_new_with_mnemonic ("_Baselines");
2435 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (self->baselines), TRUE);
2436 gtk_box_pack_start (GTK_BOX (actions), self->baselines, FALSE, TRUE, 0);
2438 g_signal_connect_swapped (self->baselines, "toggled",
2439 G_CALLBACK (gtk_widget_queue_draw),
2442 self->interiour = gtk_check_button_new_with_mnemonic ("_Interiours");
2443 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (self->interiour), TRUE);
2444 gtk_box_pack_start (GTK_BOX (actions), self->interiour, FALSE, TRUE, 0);
2446 g_signal_connect_swapped (self->interiour, "toggled",
2447 G_CALLBACK (gtk_widget_queue_draw),
2450 self->exteriour = gtk_check_button_new_with_mnemonic ("_Exteriours");
2451 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (self->exteriour), TRUE);
2452 gtk_box_pack_start (GTK_BOX (actions), self->exteriour, FALSE, TRUE, 0);
2454 g_signal_connect_swapped (self->exteriour, "toggled",
2455 G_CALLBACK (gtk_widget_queue_draw),
2458 self->statusbar = gtk_label_new ("No widget selected.\n");
2459 gtk_misc_set_alignment (GTK_MISC (self->statusbar), 0.0, 0.5);
2460 gtk_label_set_ellipsize (GTK_LABEL (self->statusbar),
2461 PANGO_ELLIPSIZE_END);
2463 table = gtk_table_new (3, 2, FALSE);
2465 gtk_table_set_col_spacings (GTK_TABLE (table), 6);
2466 gtk_table_set_row_spacings (GTK_TABLE (table), 6);
2467 gtk_container_set_border_width (GTK_CONTAINER (table), 6);
2469 gtk_table_attach (GTK_TABLE (table), actions, 0, 2, 0, 1, GTK_FILL | GTK_EXPAND, GTK_FILL, 0, 0);
2470 gtk_table_attach (GTK_TABLE (table), scrolled, 0, 1, 1, 2, GTK_FILL, GTK_FILL | GTK_EXPAND, 0, 0);
2471 gtk_table_attach (GTK_TABLE (table), self->notebook, 1, 2, 1, 2, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, 0, 0);
2472 gtk_table_attach (GTK_TABLE (table), self->statusbar, 0, 2, 2, 3, GTK_FILL | GTK_EXPAND, GTK_FILL, 0, 0);
2474 self->window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
2476 g_object_connect (self->window,
2477 "signal::button-press-event", button_press_event_cb, self,
2478 "signal::destroy", gtk_main_quit, NULL,
2481 g_timeout_add (200, watch_pointer_cb, self);
2483 gtk_window_set_title (GTK_WINDOW (self->window), "Testing GtkExtendedLayout");
2484 gtk_widget_add_events (self->window, GDK_BUTTON_PRESS_MASK);
2485 gtk_container_add (GTK_CONTAINER (self->window), table);
2486 gtk_widget_grab_focus (view);
2490 test_suite_new (gchar *arg0)
2492 TestSuite* self = g_new0 (TestSuite, 1);
2494 test_suite_setup_ui (self);
2496 test_suite_append (self, natural_size_test_new (self, FALSE, FALSE));
2497 test_suite_append (self, natural_size_test_new (self, TRUE, FALSE));
2498 test_suite_append (self, natural_size_test_new (self, FALSE, TRUE));
2499 test_suite_append (self, natural_size_test_new (self, TRUE, TRUE));
2500 test_suite_append (self, natural_size_test_misc_new (self, arg0));
2501 test_suite_append (self, size_for_allocation_test_new (self, TRUE, FALSE));
2502 test_suite_append (self, size_for_allocation_test_new (self, FALSE, FALSE));
2503 test_suite_append (self, size_for_allocation_test_new (self, TRUE, TRUE));
2504 test_suite_append (self, size_for_allocation_test_new (self, FALSE, TRUE));
2505 test_suite_append (self, baseline_test_new (self));
2506 test_suite_append (self, baseline_test_bin_new (self));
2508 test_suite_append (self, baseline_test_hbox_new (self, FALSE));
2509 test_suite_append (self, baseline_test_hbox_new (self, TRUE));
2512 test_suite_setup_results_page (self);
2518 on_embedding_timeout (gpointer data)
2520 GdkNativeWindow plug_id = GPOINTER_TO_INT (data);
2521 g_printerr ("Embedding timeout expired for plug %d. Aborting.\n", plug_id);
2527 on_embedded (GtkWidget *widget,
2530 g_source_remove (GPOINTER_TO_INT (data));
2534 create_plug (gboolean ellipsize,
2537 GtkWidget *plug, *label;
2538 GdkNativeWindow plug_id;
2542 label = gtk_label_new ("Hello World");
2545 gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_END);
2547 gtk_label_set_angle (GTK_LABEL (label), 90);
2549 plug = gtk_plug_new (0);
2550 gtk_container_add (GTK_CONTAINER (plug), label);
2551 gtk_widget_show_all (plug);
2553 plug_id = gtk_plug_get_id (GTK_PLUG (plug));
2554 timeout = g_timeout_add (5 * 1000, on_embedding_timeout,
2555 GINT_TO_POINTER (plug_id));
2557 g_signal_connect (plug, "embedded",
2558 G_CALLBACK (on_embedded),
2559 GINT_TO_POINTER (timeout));
2560 g_signal_connect (plug, "delete-event",
2561 G_CALLBACK (gtk_main_quit),
2564 g_print ("%d\n", plug_id);
2568 main (int argc, char *argv[])
2570 GOptionContext *options;
2571 TestSuite *suite = NULL;
2572 GError *error = NULL;
2574 gboolean ellipsize = FALSE;
2575 gboolean vertical = FALSE;
2576 gint initial_page = 0;
2577 gchar *action = NULL;
2579 GOptionEntry entries[] =
2581 { "action", 'a', 0, G_OPTION_ARG_STRING, &action, "Action to perform", NULL },
2582 { "initial-page", 'p', 0, G_OPTION_ARG_INT, &initial_page, "Initial page of the test suite", NULL },
2583 { "ellipsize", 0, 0, G_OPTION_ARG_NONE, &ellipsize, "Add ellipses to labels", NULL },
2584 { "vertical", 0, 0, G_OPTION_ARG_NONE, &vertical, "Render vertical layout", NULL },
2588 gtk_init (&argc, &argv);
2590 options = g_option_context_new (NULL);
2591 g_option_context_add_main_entries (options, entries, NULL);
2592 g_option_context_add_group (options, gtk_get_option_group (TRUE));
2593 g_option_context_parse (options, &argc, &argv, &error);
2597 g_print ("Usage Error: %s\n", error->message);
2601 if (action && g_str_equal (action, "create-plug"))
2603 create_plug (ellipsize, vertical);
2607 suite = test_suite_new (argv[0]);
2608 gtk_widget_show_all (suite->window);
2610 gtk_notebook_set_current_page (GTK_NOTEBOOK (suite->notebook),
2617 test_suite_free (suite);
2622 /* vim: set sw=2 sta et: */