[gtk+/extended-layout-jhs: 57/64] Start real testing of height-for-width and width-for-height. Add
- From: Johannes Schmid <jhs src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gtk+/extended-layout-jhs: 57/64] Start real testing of height-for-width and width-for-height. Add
- Date: Wed, 25 Nov 2009 11:23:41 +0000 (UTC)
commit 79c40197a05d6c3319f69d4fa803972af1d960b5
Author: Mathias Hasselmann <mathias hasselmann gmx de>
Date: Mon Aug 20 17:59:44 2007 +0000
Start real testing of height-for-width and width-for-height. Add
2007-08-20 Mathias Hasselmann <mathias hasselmann gmx de>
* tests/testextendedlayout.c: Start real testing of height-for-width
and width-for-height.
* gtk/gtklabel.c, gtk/gtklabel.h, gtk/gtk.symbols: Add "full-size"
property to be able to provide a meaningfull implementation of
height-for-width and width-for-height.
* gtk/gtkvbox.c: Consider height-for-width information.
svn path=/branches/extended-layout/; revision=18657
ChangeLog.gtk-extended-layout | 9 ++++
gtk/gtk.symbols | 2 +
gtk/gtklabel.c | 105 +++++++++++++++++++++++++++++++----------
gtk/gtklabel.h | 3 +
gtk/gtkvbox.c | 75 +++++++++++++++++++++--------
tests/testextendedlayout.c | 79 +++++++++++++++++++++---------
6 files changed, 203 insertions(+), 70 deletions(-)
---
diff --git a/ChangeLog.gtk-extended-layout b/ChangeLog.gtk-extended-layout
index 89810f1..aaed61f 100644
--- a/ChangeLog.gtk-extended-layout
+++ b/ChangeLog.gtk-extended-layout
@@ -1,3 +1,12 @@
+2007-08-20 Mathias Hasselmann <mathias hasselmann gmx de>
+
+ * tests/testextendedlayout.c: Start real testing of height-for-width
+ and width-for-height.
+ * gtk/gtklabel.c, gtk/gtklabel.h, gtk/gtk.symbols: Add "full-size"
+ property to be able to provide a meaningfull implementation of
+ height-for-width and width-for-height.
+ * gtk/gtkvbox.c: Consider height-for-width information.
+
2007-08-13 Mathias Hasselmann <mathias hasselmann gmx de>
* tests/testextendedlayout.c: Provide context menu to directly select
diff --git a/gtk/gtk.symbols b/gtk/gtk.symbols
index dcca18e..1824706 100644
--- a/gtk/gtk.symbols
+++ b/gtk/gtk.symbols
@@ -2032,6 +2032,7 @@ gtk_label_get_type G_GNUC_CONST
gtk_label_get_use_markup
gtk_label_get_use_underline
gtk_label_get_width_chars
+gtk_label_get_full_size
gtk_label_new
gtk_label_new_with_mnemonic
gtk_label_select_region
@@ -2054,6 +2055,7 @@ gtk_label_set_text_with_mnemonic
gtk_label_set_use_markup
gtk_label_set_use_underline
gtk_label_set_width_chars
+gtk_label_set_full_size
#endif
#endif
diff --git a/gtk/gtklabel.c b/gtk/gtklabel.c
index 58e15cd..e738235 100644
--- a/gtk/gtklabel.c
+++ b/gtk/gtklabel.c
@@ -50,7 +50,7 @@
#define GTK_LABEL_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_LABEL, GtkLabelPrivate))
-#ifndef INFINITY /* Why don't we use C99 again? */
+#ifndef INFINITY /* Why again don't we use C99? */
#define INFINITY HUGE_VAL
#endif
@@ -60,6 +60,7 @@ typedef struct
gint width_chars;
gint max_width_chars;
gint baseline_offset;
+ gboolean full_size;
}
GtkLabelPrivate;
@@ -102,7 +103,8 @@ enum {
PROP_WIDTH_CHARS,
PROP_SINGLE_LINE_MODE,
PROP_ANGLE,
- PROP_MAX_WIDTH_CHARS
+ PROP_MAX_WIDTH_CHARS,
+ PROP_FULL_SIZE
};
static guint signals[LAST_SIGNAL] = { 0 };
@@ -524,6 +526,23 @@ gtk_label_class_init (GtkLabelClass *class)
G_MAXINT,
-1,
GTK_PARAM_READWRITE));
+
+ /**
+ * GtkLabel:full-size:
+ *
+ * Use the entire space the widget got assigned for text wrapping. Overrides
+ * any #GtkLabel:width-chars, #GtkLabel:max-width-chars and screen size based
+ * constraints. Requires #GtkLabel:angle to be 0°, 90°, 180° or 270°.
+ *
+ * Since: 2.14
+ **/
+ g_object_class_install_property (gobject_class,
+ PROP_FULL_SIZE,
+ g_param_spec_boolean ("full-size",
+ P_("Full size"),
+ P_("Use the entire size of the widget to wrap text"),
+ FALSE,
+ GTK_PARAM_READWRITE));
/*
* Key bindings
*/
@@ -700,6 +719,9 @@ gtk_label_set_property (GObject *object,
case PROP_MAX_WIDTH_CHARS:
gtk_label_set_max_width_chars (label, g_value_get_int (value));
break;
+ case PROP_FULL_SIZE:
+ gtk_label_set_full_size (label, g_value_get_boolean (value));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -783,6 +805,9 @@ gtk_label_get_property (GObject *object,
case PROP_MAX_WIDTH_CHARS:
g_value_set_int (value, gtk_label_get_max_width_chars (label));
break;
+ case PROP_FULL_SIZE:
+ g_value_set_int (value, gtk_label_get_full_size (label));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -1966,7 +1991,7 @@ get_label_wrap_width (GtkLabel *label)
GtkLabelPrivate *priv;
priv = GTK_LABEL_GET_PRIVATE (label);
-
+
if (priv->wrap_width < 0)
{
if (priv->width_chars > 0 || priv->max_width_chars > 0)
@@ -2080,14 +2105,14 @@ gtk_label_ensure_layout (GtkLabel *label)
wrap_width = get_label_wrap_width (label);
width = MIN (width, wrap_width);
- width = MIN (width,
+ width = MIN (width,
PANGO_SCALE * (gdk_screen_get_width (screen) + 1) / 2);
-
+
pango_layout_set_width (label->layout, width);
pango_layout_get_extents (label->layout, NULL, &logical_rect);
width = logical_rect.width;
height = logical_rect.height;
-
+
/* Unfortunately, the above may leave us with a very unbalanced looking paragraph,
* so we try short search for a narrower width that leaves us with the same height
*/
@@ -2212,13 +2237,11 @@ static void
gtk_label_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
- GtkLabel *label;
-
- label = GTK_LABEL (widget);
+ GtkLabel *label = GTK_LABEL (widget);
(* GTK_WIDGET_CLASS (gtk_label_parent_class)->size_allocate) (widget, allocation);
- if (label->ellipsize)
+ if (label->ellipsize || GTK_LABEL_GET_PRIVATE (label)->full_size)
{
if (label->layout)
{
@@ -2383,7 +2406,7 @@ get_layout_location (GtkLabel *label,
else
xalign = 1.0 - misc->xalign;
- if (label->ellipsize || priv->width_chars > 0)
+ if (label->ellipsize || priv->width_chars > 0 || GTK_LABEL_GET_PRIVATE (label)->full_size)
{
int width;
PangoRectangle logical;
@@ -3737,6 +3760,32 @@ gtk_label_set_use_underline (GtkLabel *label,
gtk_label_setup_mnemonic (label, label->mnemonic_keyval);
}
+gboolean
+gtk_label_get_full_size (GtkLabel *label)
+{
+ g_return_val_if_fail (GTK_IS_LABEL (label), FALSE);
+ return GTK_LABEL_GET_PRIVATE (label)->full_size;
+}
+
+void
+gtk_label_set_full_size (GtkLabel *label,
+ gboolean setting)
+{
+ GtkLabelPrivate *priv;
+
+ g_return_if_fail (GTK_IS_LABEL (label));
+ priv = GTK_LABEL_GET_PRIVATE (label);
+
+ if (priv->full_size != setting)
+ {
+ priv->full_size = setting;
+
+ g_object_notify (G_OBJECT (label), "full-size");
+ gtk_label_invalidate_wrap_width (label);
+ gtk_widget_queue_resize (GTK_WIDGET (label));
+ }
+}
+
/**
* gtk_label_get_use_underline:
* @label: a #GtkLabel
@@ -4301,39 +4350,44 @@ gtk_label_do_popup (GtkLabel *label,
static GtkExtendedLayoutFeatures
gtk_label_extended_layout_get_features (GtkExtendedLayout *layout)
{
+ GtkLabel *label = GTK_LABEL (layout);
GtkExtendedLayoutFeatures features;
- GtkLabel *label;
features =
GTK_EXTENDED_LAYOUT_NATURAL_SIZE |
GTK_EXTENDED_LAYOUT_BASELINES;
- label = GTK_LABEL (layout);
if (label->wrap)
- features |= GTK_EXTENDED_LAYOUT_HEIGHT_FOR_WIDTH;
+ {
+ gdouble angle = gtk_label_get_angle (label);
+
+ if (0 == angle || 180 == angle)
+ features |= GTK_EXTENDED_LAYOUT_HEIGHT_FOR_WIDTH;
+ else if (90 == angle || 270 == angle)
+ features |= GTK_EXTENDED_LAYOUT_WIDTH_FOR_HEIGHT;
+ }
return features;
}
static gint
-gtk_label_extended_layout_get_height_for_width (GtkExtendedLayout *layout,
- gint width)
+gtk_label_extended_layout_get_size_for_other (GtkExtendedLayout *layout,
+ gint size)
{
+ GtkLabel *label = GTK_LABEL (layout);
+ gdouble angle = gtk_label_get_angle (label);
PangoLayout *tmp;
- GtkLabel *label;
- gint height;
-
- label = GTK_LABEL (layout);
- g_return_val_if_fail (label->wrap, -1);
+ // this test is slightly more tolerant than the get_features test
+ g_assert (0 == (((gint)angle) % 90));
gtk_label_ensure_layout (label);
tmp = pango_layout_copy (label->layout);
- pango_layout_set_width (tmp, PANGO_SCALE * width);
- pango_layout_get_pixel_size (tmp, NULL, &height);
+ pango_layout_set_width (tmp, PANGO_SCALE * size);
+ pango_layout_get_pixel_size (tmp, NULL, &size);
g_object_unref (tmp);
- return height;
+ return size;
}
static void
@@ -4406,7 +4460,8 @@ static void
gtk_label_extended_layout_interface_init (GtkExtendedLayoutIface *iface)
{
iface->get_features = gtk_label_extended_layout_get_features;
- iface->get_height_for_width = gtk_label_extended_layout_get_height_for_width;
+ iface->get_height_for_width = gtk_label_extended_layout_get_size_for_other;
+ iface->get_width_for_height = gtk_label_extended_layout_get_size_for_other;
iface->get_natural_size = gtk_label_extended_layout_get_natural_size;
iface->get_baselines = gtk_label_extended_layout_get_baselines;
iface->set_baseline_offset = gtk_label_extended_layout_set_baseline_offset;
diff --git a/gtk/gtklabel.h b/gtk/gtklabel.h
index e13a716..18a970e 100644
--- a/gtk/gtklabel.h
+++ b/gtk/gtklabel.h
@@ -118,6 +118,9 @@ gboolean gtk_label_get_use_markup (GtkLabel *label);
void gtk_label_set_use_underline (GtkLabel *label,
gboolean setting);
gboolean gtk_label_get_use_underline (GtkLabel *label);
+void gtk_label_set_full_size (GtkLabel *label,
+ gboolean setting);
+gboolean gtk_label_get_full_size (GtkLabel *label);
void gtk_label_set_markup_with_mnemonic (GtkLabel *label,
const gchar *str);
diff --git a/gtk/gtkvbox.c b/gtk/gtkvbox.c
index d0860c5..e8d90d0 100644
--- a/gtk/gtkvbox.c
+++ b/gtk/gtkvbox.c
@@ -72,11 +72,38 @@ gtk_vbox_new (gboolean homogeneous,
return GTK_WIDGET (vbox);
}
+typedef void (*GtkChildSizeRequest) (GtkWidget *child,
+ GtkRequisition *requisition,
+ GtkWidget *widget);
static void
-gtk_vbox_real_size_request (GtkWidget *widget,
- GtkRequisition *requisition,
- gboolean consider_natural_size)
+gtk_vbox_natural_size_request (GtkWidget *child,
+ GtkRequisition *requisition,
+ GtkWidget *widget)
+{
+ GtkExtendedLayoutFeatures features = 0;
+
+ if (GTK_IS_EXTENDED_LAYOUT (child))
+ features = gtk_extended_layout_get_features ((GtkExtendedLayout*) child);
+
+ if (features & GTK_EXTENDED_LAYOUT_HEIGHT_FOR_WIDTH)
+ {
+ requisition->width = widget->allocation.width;
+ requisition->height = gtk_extended_layout_get_height_for_width (
+ (GtkExtendedLayout*) child, widget->allocation.width);
+ }
+ else if (features & GTK_EXTENDED_LAYOUT_NATURAL_SIZE)
+ gtk_extended_layout_get_natural_size ((GtkExtendedLayout*) child, requisition);
+ else
+ gtk_widget_size_request (child, requisition);
+
+g_print ("%s: %dx%d (%dx%d)\n", G_OBJECT_TYPE_NAME (child), requisition->width, requisition->height, child->allocation.width, child->allocation.height);
+}
+
+static void
+gtk_vbox_real_size_request (GtkWidget *widget,
+ GtkRequisition *requisition,
+ GtkChildSizeRequest size_request_func)
{
GtkBox *box;
GtkBoxChild *child;
@@ -98,11 +125,7 @@ gtk_vbox_real_size_request (GtkWidget *widget,
if (GTK_WIDGET_VISIBLE (child->widget))
{
- if (consider_natural_size && GTK_EXTENDED_LAYOUT_HAS_NATURAL_SIZE (child->widget))
- gtk_extended_layout_get_natural_size (GTK_EXTENDED_LAYOUT (child->widget),
- &child_requisition);
- else
- gtk_widget_size_request (child->widget, &child_requisition);
+ size_request_func (child->widget, &child_requisition, widget);
if (box->homogeneous)
{
@@ -135,7 +158,7 @@ static void
gtk_vbox_size_request (GtkWidget *widget,
GtkRequisition *requisition)
{
- gtk_vbox_real_size_request (widget, requisition, FALSE);
+ gtk_vbox_real_size_request (widget, requisition, (GtkChildSizeRequest)gtk_widget_size_request);
}
static void
@@ -179,12 +202,14 @@ gtk_vbox_size_allocate (GtkWidget *widget,
gint *minimum_requisitions;
gint available, natural, extra;
- gint natural_height;
+ gint minimum_height, natural_height;
gint i;
border_width = GTK_CONTAINER (box)->border_width;
+ minimum_height = 0;
natural_height = 0;
+
natural_requisitions = g_newa (gint, nvis_children);
minimum_requisitions = g_newa (gint, nvis_children);
@@ -202,19 +227,27 @@ gtk_vbox_size_allocate (GtkWidget *widget,
gtk_widget_size_request (child->widget, &child_requisition);
minimum_requisitions[i] = child_requisition.height;
+ natural_requisitions[i] = 0;
- if (GTK_EXTENDED_LAYOUT_HAS_NATURAL_SIZE (child->widget))
+ if (GTK_IS_EXTENDED_LAYOUT (child->widget))
{
- gtk_extended_layout_get_natural_size (
- GTK_EXTENDED_LAYOUT (child->widget),
- &child_requisition);
- natural_requisitions[i] =
- child_requisition.height -
- minimum_requisitions[i];
+ GtkExtendedLayout *layout = (GtkExtendedLayout*)child->widget;
+ GtkExtendedLayoutFeatures features = gtk_extended_layout_get_features (layout);
+
+ if (features & GTK_EXTENDED_LAYOUT_HEIGHT_FOR_WIDTH)
+ {
+ gint height = gtk_extended_layout_get_height_for_width (layout, allocation->width);
+ minimum_requisitions[i] = MIN (minimum_requisitions[i], height);
+ }
+ else if (features & GTK_EXTENDED_LAYOUT_NATURAL_SIZE)
+ {
+ gtk_extended_layout_get_natural_size (layout, &child_requisition);
+ natural_requisitions[i] = child_requisition.height - minimum_requisitions[i];
+ }
+
}
- else
- natural_requisitions[i] = 0;
+ minimum_height += minimum_requisitions[i];
natural_height += natural_requisitions[i++];
}
}
@@ -230,7 +263,7 @@ gtk_vbox_size_allocate (GtkWidget *widget,
{
if (nexpand_children > 0 || natural_height > 0)
{
- available = (gint)allocation->height - widget->requisition.height;
+ available = (gint)allocation->height - minimum_height;
natural = MAX (0, MIN (available, natural_height));
available -= natural;
}
@@ -339,7 +372,7 @@ static void
gtk_vbox_extended_layout_get_natural_size (GtkExtendedLayout *layout,
GtkRequisition *requisition)
{
- gtk_vbox_real_size_request (GTK_WIDGET (layout), requisition, TRUE);
+ gtk_vbox_real_size_request (GTK_WIDGET (layout), requisition, gtk_vbox_natural_size_request);
}
static void
diff --git a/tests/testextendedlayout.c b/tests/testextendedlayout.c
index ddb9a5e..5dd0f30 100644
--- a/tests/testextendedlayout.c
+++ b/tests/testextendedlayout.c
@@ -920,37 +920,67 @@ natural_size_test_misc_new (TestSuite *suite,
}
static TestCase*
-height_for_width_test_new (TestSuite *suite)
+height_for_width_test_new (TestSuite *suite,
+ gboolean vertical)
{
- PangoLayout *layout;
- PangoRectangle log;
- GtkWidget *child;
+ GtkWidget *box, *child;
+ TestCase *test;
+ int i;
- TestCase *test = test_case_new (suite, "Height for Width", NULL,
- gtk_hbox_new (FALSE, 12));
+ if (vertical)
+ {
+ test = test_case_new (suite, "Height for Width", NULL, gtk_hpaned_new ());
+ box = gtk_vbox_new (FALSE, 6);
- gtk_container_set_border_width (GTK_CONTAINER (test->widget), 12);
+ child = gtk_label_new ("Move the handle to test\n"
+ "height-for-width requests");
- child = gtk_label_new (lorem_ipsum);
- gtk_label_set_line_wrap (GTK_LABEL (child), TRUE);
- gtk_label_set_use_markup (GTK_LABEL (child), TRUE);
- gtk_box_pack_start (GTK_BOX (test->widget), child, TRUE, TRUE, 0);
- layout = gtk_label_get_layout (GTK_LABEL (child));
+ gtk_label_set_angle (GTK_LABEL (child), 90);
+ }
+ else
+ {
+ test = test_case_new (suite, "Width for Height", NULL, gtk_vpaned_new ());
+ box = gtk_hbox_new (FALSE, 6);
- pango_layout_get_pixel_extents (layout, NULL, &log);
- gtk_widget_set_size_request (test->widget, log.width * 3 / 2, -1);
+ child = gtk_label_new ("Move the handle to test\n"
+ "width-for-height requests");
+ }
- test_case_append_guide (test, child, GUIDE_INTERIOUR_BOTH, 0);
- test_case_append_guide (test, child, GUIDE_EXTERIOUR_BOTH, 0);
- test_case_append_guide (test, child, GUIDE_BASELINE, 0);
+ gtk_container_set_border_width (GTK_CONTAINER (test->widget), 6);
+ gtk_container_set_border_width (GTK_CONTAINER (box), 6);
+ gtk_misc_set_padding (GTK_MISC (child), 6, 6);
- child = gtk_button_new ();
- gtk_container_add (GTK_CONTAINER (child),
- gtk_image_new_from_stock (GTK_STOCK_DIALOG_INFO,
- GTK_ICON_SIZE_DIALOG));
- gtk_box_pack_start (GTK_BOX (test->widget), child, FALSE, TRUE, 0);
+ gtk_paned_pack1 (GTK_PANED (test->widget), box, TRUE, FALSE);
+ gtk_paned_pack2 (GTK_PANED (test->widget), child, FALSE, FALSE);
- test_case_append_guide (test, child, GUIDE_EXTERIOUR_BOTH, 1);
+ for (i = 0; i < 4; ++i)
+ {
+ if (2 != i)
+ {
+ child = gtk_label_new (lorem_ipsum);
+ gtk_label_set_line_wrap (GTK_LABEL (child), TRUE);
+ gtk_label_set_use_markup (GTK_LABEL (child), TRUE);
+ test_case_append_guide (test, child, GUIDE_EXTERIOUR_BOTH, -1);
+ test_case_append_guide (test, child, GUIDE_INTERIOUR_BOTH, -1);
+ gtk_box_pack_start (GTK_BOX (box), child, FALSE, TRUE, 0);
+
+ if (i > 0)
+ gtk_label_set_full_size (GTK_LABEL (child), TRUE);
+
+ if (i > 2)
+ gtk_label_set_angle (GTK_LABEL (child), vertical ? 180 : 270);
+ else if (!vertical)
+ gtk_label_set_angle (GTK_LABEL (child), 90);
+ }
+ else
+ {
+ child = gtk_button_new ();
+ gtk_container_add (GTK_CONTAINER (child),
+ gtk_image_new_from_stock (GTK_STOCK_DIALOG_INFO,
+ GTK_ICON_SIZE_DIALOG));
+ gtk_box_pack_start (GTK_BOX (box), child, TRUE, TRUE, 0);
+ }
+ }
return test;
}
@@ -2429,7 +2459,8 @@ test_suite_new (gchar *arg0)
test_suite_append (self, natural_size_test_new (self, FALSE, TRUE));
test_suite_append (self, natural_size_test_new (self, TRUE, TRUE));
test_suite_append (self, natural_size_test_misc_new (self, arg0));
- test_suite_append (self, height_for_width_test_new (self));
+ test_suite_append (self, height_for_width_test_new (self, TRUE));
+ test_suite_append (self, height_for_width_test_new (self, FALSE));
test_suite_append (self, baseline_test_new (self));
test_suite_append (self, baseline_test_bin_new (self));
test_suite_append (self, baseline_test_hbox_new (self, FALSE));
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]