diff --git a/ChangeLog.gtk-extended-layout b/ChangeLog.gtk-extended-layout index 3779310868..e6d0730406 100644 --- a/ChangeLog.gtk-extended-layout +++ b/ChangeLog.gtk-extended-layout @@ -1,3 +1,8 @@ +2007-06-20 Mathias Hasselmann + + * gtk/gtkbin.c, tests/autotestextendedlayout.c, + tests/testextendedlayout.c: Implement GtkExtendedLayout for GtkBin. + 2007-06-20 Mathias Hasselmann * gtk/gtklabel.c, tests/autotestextendedlayout.c: diff --git a/gtk/gtkbin.c b/gtk/gtkbin.c index d6f5d5e356..d4b6e77b15 100644 --- a/gtk/gtkbin.c +++ b/gtk/gtkbin.c @@ -26,6 +26,7 @@ #include #include "gtkbin.h" +#include "gtkextendedlayout.h" #include "gtkintl.h" #include "gtkalias.h" @@ -34,13 +35,16 @@ static void gtk_bin_add (GtkContainer *container, static void gtk_bin_remove (GtkContainer *container, GtkWidget *widget); static void gtk_bin_forall (GtkContainer *container, - gboolean include_internals, + gboolean include_internals, GtkCallback callback, gpointer callback_data); static GType gtk_bin_child_type (GtkContainer *container); +static void gtk_bin_extended_layout_interface_init (GtkExtendedLayoutIface *iface); -G_DEFINE_ABSTRACT_TYPE (GtkBin, gtk_bin, GTK_TYPE_CONTAINER) +G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GtkBin, gtk_bin, GTK_TYPE_CONTAINER, + G_IMPLEMENT_INTERFACE (GTK_TYPE_EXTENDED_LAYOUT, + gtk_bin_extended_layout_interface_init)) static void gtk_bin_class_init (GtkBinClass *class) @@ -151,5 +155,90 @@ gtk_bin_get_child (GtkBin *bin) return bin->child; } +static GtkExtendedLayoutFeatures +gtk_bin_extended_layout_get_features (GtkExtendedLayout *layout) +{ + GtkBin *bin = GTK_BIN (layout); + + if (GTK_IS_EXTENDED_LAYOUT (bin->child)) + return gtk_extended_layout_get_features (GTK_EXTENDED_LAYOUT (bin->child)); + + return 0; +} + +static gint +gtk_bin_extended_layout_get_height_for_width (GtkExtendedLayout *layout, + gint width) +{ + GtkBin *bin = GTK_BIN (layout); + + g_return_val_if_fail (GTK_IS_EXTENDED_LAYOUT (bin->child), -1); + + layout = GTK_EXTENDED_LAYOUT (bin->child); + return gtk_extended_layout_get_height_for_width (layout, width); +} + +static gint +gtk_bin_extended_layout_get_width_for_height (GtkExtendedLayout *layout, + gint height) +{ + GtkBin *bin = GTK_BIN (layout); + + g_return_val_if_fail (GTK_IS_EXTENDED_LAYOUT (bin->child), -1); + + layout = GTK_EXTENDED_LAYOUT (bin->child); + return gtk_extended_layout_get_width_for_height (layout, height); +} + +static void +gtk_bin_extended_layout_get_natural_size (GtkExtendedLayout *layout, + GtkRequisition *requisition) +{ + GtkBin *bin = GTK_BIN (layout); + + g_return_if_fail (GTK_IS_EXTENDED_LAYOUT (bin->child)); + + layout = GTK_EXTENDED_LAYOUT (bin->child); + return gtk_extended_layout_get_natural_size (layout, requisition); +} + +static gint +gtk_bin_extended_layout_get_baselines (GtkExtendedLayout *layout, + gint **baselines) +{ + GtkBin *bin = GTK_BIN (layout); + gint *baseptr, *baseend; + gint num_lines, dy; + + g_return_val_if_fail (GTK_IS_EXTENDED_LAYOUT (bin->child), -1); + + layout = GTK_EXTENDED_LAYOUT (bin->child); + num_lines = gtk_extended_layout_get_baselines (layout, baselines); + + if (baselines) + { + gtk_widget_translate_coordinates (bin->child, GTK_WIDGET (bin), + 0, 0, NULL, &dy); + + baseptr = *baselines; + baseend = baseptr + num_lines; + + while (baseptr < baseend) + *baseptr++ += dy; + } + + return num_lines; +} + +static void +gtk_bin_extended_layout_interface_init (GtkExtendedLayoutIface *iface) +{ + iface->get_features = gtk_bin_extended_layout_get_features; + iface->get_height_for_width = gtk_bin_extended_layout_get_height_for_width; + iface->get_width_for_height = gtk_bin_extended_layout_get_width_for_height; + iface->get_natural_size = gtk_bin_extended_layout_get_natural_size; + iface->get_baselines = gtk_bin_extended_layout_get_baselines; +} + #define __GTK_BIN_C__ #include "gtkaliasdef.c" diff --git a/tests/autotestextendedlayout.c b/tests/autotestextendedlayout.c index 49029b42d7..74f141ee42 100644 --- a/tests/autotestextendedlayout.c +++ b/tests/autotestextendedlayout.c @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -321,6 +322,66 @@ gtk_label_test_extended_layout (void) gtk_label_test_natural_size (); } +static void +gtk_bin_test_extended_layout (void) +{ + const GType types[] = + { + GTK_TYPE_ALIGNMENT, GTK_TYPE_BUTTON, + GTK_TYPE_EVENT_BOX, GTK_TYPE_FRAME, + G_TYPE_INVALID + }; + + GtkExtendedLayoutFeatures features; + GtkExtendedLayoutIface *iface; + GtkExtendedLayout *layout; + GtkWidget *label; + GtkBin *bin; + + int i; + + for (i = 0; types[i]; ++i) + { + bin = g_object_ref_sink (g_object_new (types[i], NULL)); + layout = GTK_EXTENDED_LAYOUT (bin); + + label = gtk_label_new (g_type_name (types[i])); + gtk_container_add (GTK_CONTAINER (bin), label); + + /* vtable */ + + log_test (GTK_IS_EXTENDED_LAYOUT (bin)); + iface = GTK_EXTENDED_LAYOUT_GET_IFACE (bin); + + log_test (NULL != iface->get_features); + log_test (NULL != iface->get_height_for_width); + log_test (NULL != iface->get_width_for_height); + log_test (NULL != iface->get_natural_size); + log_test (NULL != iface->get_baselines); + + /* feature set */ + + features = gtk_extended_layout_get_features (layout); + + log_test (0 == (features & GTK_EXTENDED_LAYOUT_HEIGHT_FOR_WIDTH)); + log_test (0 == (features & GTK_EXTENDED_LAYOUT_WIDTH_FOR_HEIGHT)); + log_test (0 != (features & GTK_EXTENDED_LAYOUT_NATURAL_SIZE)); + log_test (0 != (features & GTK_EXTENDED_LAYOUT_BASELINES)); + + gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); + features = gtk_extended_layout_get_features (layout); + + log_test (0 != (features & GTK_EXTENDED_LAYOUT_HEIGHT_FOR_WIDTH)); + log_test (0 == (features & GTK_EXTENDED_LAYOUT_WIDTH_FOR_HEIGHT)); + log_test (0 != (features & GTK_EXTENDED_LAYOUT_NATURAL_SIZE)); + log_test (0 != (features & GTK_EXTENDED_LAYOUT_BASELINES)); + + g_object_unref (bin); + } + + log_testf (FALSE, "%s", "TODO: Provide real tests for GtkBin"); +} + /*****************************************************************************/ int @@ -331,6 +392,7 @@ main(int argc, char **argv) gtk_init (&argc, &argv); gtk_label_test_extended_layout (); + gtk_bin_test_extended_layout (); log_testi (0, num_warnings); log_testi (0, num_errors); diff --git a/tests/testextendedlayout.c b/tests/testextendedlayout.c index f39936fbcc..4a6645da5c 100644 --- a/tests/testextendedlayout.c +++ b/tests/testextendedlayout.c @@ -298,6 +298,68 @@ create_baseline_test () return test; } +static TestCase* +create_baseline_test_bin () +{ + const GType types[] = + { + GTK_TYPE_ALIGNMENT, GTK_TYPE_BUTTON, + GTK_TYPE_EVENT_BOX, GTK_TYPE_FRAME, + G_TYPE_INVALID + }; + + const gchar *markup[] = + { + "xx-Small", + "Bold", + "Large", + "xx-Large", + NULL + }; + + GtkWidget *bin; + GtkWidget *label; + GtkWidget *table; + + int i, j; + + TestCase *test = test_case_new ("Baseline Alignment for GtkBin", + gtk_alignment_new (0.5, 0.5, 0.0, 0.0)); + + table = gtk_table_new (G_N_ELEMENTS (types) - 1, + G_N_ELEMENTS (markup), + FALSE); + + gtk_container_set_border_width (GTK_CONTAINER (table), 12); + gtk_table_set_col_spacings (GTK_TABLE (table), 6); + gtk_table_set_row_spacings (GTK_TABLE (table), 6); + gtk_container_add (GTK_CONTAINER (test->widget), table); + + for (i = 0; types[i]; ++i) + { + label = gtk_label_new (g_type_name (types[i])); + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); + + gtk_table_attach (GTK_TABLE (table), label, 0, 1, + i, i + 1, GTK_FILL, GTK_FILL, 0, 0); + + for (j = 0; markup[j]; ++j) + { + bin = g_object_new (types[i], NULL); + label = gtk_label_new (NULL); + + gtk_label_set_markup (GTK_LABEL (label), markup[j]); + gtk_container_add (GTK_CONTAINER (bin), label); + + test_case_append_guide (test, bin, GUIDE_BASELINE, i); + gtk_table_attach (GTK_TABLE (table), bin, j + 1, j + 2, + i, i + 1, GTK_FILL, GTK_FILL, 0, 0); + } + } + + return test; +} + static gboolean get_extends (GtkWidget *widget, GtkWidget *toplevel, @@ -414,9 +476,18 @@ draw_baseline (GdkDrawable *drawable, const gint xe = xa + extends->width - 1; const gint ya = y0 + extends->y + baseline; - gdk_draw_line (drawable, gc, x0, ya, x0 + cx, ya); gdk_draw_line (drawable, gc, xa, ya - 5, xa, ya + 2); + gdk_draw_line (drawable, gc, xa + 2, ya, xe - 2, ya); gdk_draw_line (drawable, gc, xe, ya - 5, xe, ya + 2); + + gdk_gc_set_line_attributes (gc, 1, GDK_LINE_ON_OFF_DASH, + GDK_CAP_NOT_LAST, GDK_JOIN_MITER); + + gdk_draw_line (drawable, gc, x0, ya, xa - 2, ya); + gdk_draw_line (drawable, gc, xe + 2, ya, x0 + cx, ya); + + gdk_gc_set_line_attributes (gc, 1, GDK_LINE_SOLID, + GDK_CAP_NOT_LAST, GDK_JOIN_MITER); } static void @@ -577,6 +648,7 @@ draw_guides (gpointer data) GdkDrawable *drawable; const GList *iter; + gint8 dashes[] = { 3, 3 }; GdkGCValues values; GdkGC *gc; @@ -586,6 +658,8 @@ draw_guides (gpointer data) gc = gdk_gc_new_with_values (drawable, &values, GDK_GC_SUBWINDOW); + gdk_gc_set_dashes (gc, 1, dashes, 2); + for (iter = test->guides; iter; iter = iter->next) { const Guide *guide = iter->data; @@ -693,6 +767,7 @@ test_suite_new () test_suite_append (self, create_natural_size_test ()); test_suite_append (self, create_height_for_width_test ()); test_suite_append (self, create_baseline_test ()); + test_suite_append (self, create_baseline_test_bin ()); self->results = gtk_tree_store_new (COLUNN_COUNT, G_TYPE_STRING, PANGO_TYPE_WEIGHT,