From 50cbd51d269b36bf9e273a7743772e8cae23387a Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Mon, 13 Dec 2004 06:34:54 +0000 Subject: [PATCH] Add a max-width-chars property, which can be used to specify the width of 2004-12-13 Matthias Clasen * gtk/gtklabel.[hc]: Add a max-width-chars property, which can be used to specify the width of the label in characters, while still allowing it to fall short of this length if the text is shorter. (#155944, Christian Persch) * gtk/gtk.symbols: Add new symbols. --- ChangeLog | 7 ++ ChangeLog.pre-2-10 | 7 ++ ChangeLog.pre-2-6 | 7 ++ ChangeLog.pre-2-8 | 7 ++ docs/reference/ChangeLog | 4 + docs/reference/gtk/gtk-sections.txt | 2 + gtk/gtk.symbols | 2 + gtk/gtklabel.c | 127 ++++++++++++++++++++++++---- gtk/gtklabel.h | 3 + 9 files changed, 149 insertions(+), 17 deletions(-) diff --git a/ChangeLog b/ChangeLog index c6b2cf07d5..cab3090fea 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,12 @@ 2004-12-13 Matthias Clasen + * gtk/gtklabel.[hc]: Add a max-width-chars property, which can + be used to specify the width of the label in characters, while + still allowing it to fall short of this length if the text + is shorter. (#155944, Christian Persch) + + * gtk/gtk.symbols: Add new symbols. + * gtk/gtkuimanager.c (update_smart_separators): Don't let the empty menu filler affect visibility of separators. (#160500, Christian Persch) diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index c6b2cf07d5..cab3090fea 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,5 +1,12 @@ 2004-12-13 Matthias Clasen + * gtk/gtklabel.[hc]: Add a max-width-chars property, which can + be used to specify the width of the label in characters, while + still allowing it to fall short of this length if the text + is shorter. (#155944, Christian Persch) + + * gtk/gtk.symbols: Add new symbols. + * gtk/gtkuimanager.c (update_smart_separators): Don't let the empty menu filler affect visibility of separators. (#160500, Christian Persch) diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index c6b2cf07d5..cab3090fea 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,5 +1,12 @@ 2004-12-13 Matthias Clasen + * gtk/gtklabel.[hc]: Add a max-width-chars property, which can + be used to specify the width of the label in characters, while + still allowing it to fall short of this length if the text + is shorter. (#155944, Christian Persch) + + * gtk/gtk.symbols: Add new symbols. + * gtk/gtkuimanager.c (update_smart_separators): Don't let the empty menu filler affect visibility of separators. (#160500, Christian Persch) diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index c6b2cf07d5..cab3090fea 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,5 +1,12 @@ 2004-12-13 Matthias Clasen + * gtk/gtklabel.[hc]: Add a max-width-chars property, which can + be used to specify the width of the label in characters, while + still allowing it to fall short of this length if the text + is shorter. (#155944, Christian Persch) + + * gtk/gtk.symbols: Add new symbols. + * gtk/gtkuimanager.c (update_smart_separators): Don't let the empty menu filler affect visibility of separators. (#160500, Christian Persch) diff --git a/docs/reference/ChangeLog b/docs/reference/ChangeLog index 96c4b10d35..e6e4772491 100644 --- a/docs/reference/ChangeLog +++ b/docs/reference/ChangeLog @@ -1,3 +1,7 @@ +2004-12-13 Matthias Clasen + + * gtk/gtk-sections.txt: Add new label methods. + 2004-12-09 Matthias Clasen * gtk/gtk-sections.txt: Add new list store methods. diff --git a/docs/reference/gtk/gtk-sections.txt b/docs/reference/gtk/gtk-sections.txt index 01419875f8..6b84fda9af 100644 --- a/docs/reference/gtk/gtk-sections.txt +++ b/docs/reference/gtk/gtk-sections.txt @@ -1908,6 +1908,7 @@ gtk_label_set_pattern gtk_label_set_justify gtk_label_set_ellipsize gtk_label_set_width_chars +gtk_label_set_max_width_chars gtk_label_get gtk_label_parse_uline gtk_label_set_line_wrap @@ -1925,6 +1926,7 @@ gtk_label_get_attributes gtk_label_get_justify gtk_label_get_ellipsize gtk_label_get_width_chars +gtk_label_get_max_width_chars gtk_label_get_label gtk_label_get_layout gtk_label_get_line_wrap diff --git a/gtk/gtk.symbols b/gtk/gtk.symbols index da2c2d44c4..b544e25524 100644 --- a/gtk/gtk.symbols +++ b/gtk/gtk.symbols @@ -1307,6 +1307,7 @@ gtk_label_get_label gtk_label_get_layout gtk_label_get_layout_offsets gtk_label_get_line_wrap +gtk_label_get_max_width_chars gtk_label_get_mnemonic_keyval gtk_label_get_mnemonic_widget gtk_label_get_selectable @@ -1329,6 +1330,7 @@ gtk_label_set_label gtk_label_set_line_wrap gtk_label_set_markup gtk_label_set_markup_with_mnemonic +gtk_label_set_max_width_chars gtk_label_set_mnemonic_widget gtk_label_set_pattern gtk_label_set_selectable diff --git a/gtk/gtklabel.c b/gtk/gtklabel.c index bb6eb5f8da..256fbe1e74 100644 --- a/gtk/gtklabel.c +++ b/gtk/gtklabel.c @@ -48,6 +48,7 @@ typedef struct { gint width_chars; + gint max_width_chars; guint single_line_mode : 1; guint have_transform : 1; gdouble angle; @@ -91,7 +92,8 @@ enum { PROP_ELLIPSIZE, PROP_WIDTH_CHARS, PROP_SINGLE_LINE_MODE, - PROP_ANGLE + PROP_ANGLE, + PROP_MAX_WIDTH_CHARS }; static guint signals[LAST_SIGNAL] = { 0 }; @@ -440,7 +442,9 @@ gtk_label_class_init (GtkLabelClass *class) * The desired width of the label, in characters. If this property is set to * -1, the width will be calculated automatically, otherwise the label will * request either 3 characters or the property value, whichever is greater. - * + * If the width-chars property is set to a positive value, then the + * max-width-chars property is ignored. + * * Since: 2.6 **/ g_object_class_install_property (gobject_class, @@ -492,6 +496,26 @@ gtk_label_class_init (GtkLabelClass *class) 0.0, G_PARAM_READWRITE)); + /** + * GtkLabel:max-width-chars: + * + * The desired width maximal of the label, in characters. If this property + * is set to -1, the width will be calculated automatically, otherwise the + * label will request space for no more than the requested number of + * characters. If the width-chars property is set to a positive value, + * then the max-width-chars property is ignored. + * + * Since: 2.6 + **/ + g_object_class_install_property (gobject_class, + PROP_MAX_WIDTH_CHARS, + g_param_spec_int ("max_width_chars", + P_("Maximal Width In Characters"), + P_("The desired maximal width of the label, in characters"), + -1, + G_MAXINT, + -1, + G_PARAM_READWRITE)); /* * Key bindings */ @@ -622,7 +646,10 @@ gtk_label_set_property (GObject *object, break; case PROP_ANGLE: gtk_label_set_angle (label, g_value_get_double (value)); - break; + break; + case PROP_MAX_WIDTH_CHARS: + gtk_label_set_max_width_chars (label, g_value_get_int (value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -692,7 +719,7 @@ gtk_label_get_property (GObject *object, g_value_set_enum (value, label->ellipsize); break; case PROP_WIDTH_CHARS: - g_value_set_enum (value, gtk_label_get_width_chars (label)); + g_value_set_int (value, gtk_label_get_width_chars (label)); break; case PROP_SINGLE_LINE_MODE: g_value_set_boolean (value, gtk_label_get_single_line_mode (label)); @@ -700,6 +727,9 @@ gtk_label_get_property (GObject *object, case PROP_ANGLE: g_value_set_double (value, gtk_label_get_angle (label)); break; + case PROP_MAX_WIDTH_CHARS: + g_value_set_int (value, gtk_label_get_max_width_chars (label)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -717,6 +747,7 @@ gtk_label_init (GtkLabel *label) priv = GTK_LABEL_GET_PRIVATE (label); priv->width_chars = -1; priv->angle = 0.0; + priv->max_width_chars = -1; label->label = NULL; label->jtype = GTK_JUSTIFY_LEFT; @@ -1452,7 +1483,6 @@ gtk_label_get_justify (GtkLabel *label) return label->jtype; } - /** * gtk_label_set_ellipsize: * @label: a #GtkLabel @@ -1534,7 +1564,7 @@ gtk_label_set_width_chars (GtkLabel *label, * Retrieves the desired width of @label, in characters. See * gtk_label_set_width_chars(). * - * Return value: the width of a label in characters. + * Return value: the width of the label in characters. * * Since: 2.6 **/ @@ -1546,6 +1576,53 @@ gtk_label_get_width_chars (GtkLabel *label) return GTK_LABEL_GET_PRIVATE (label)->width_chars; } +/** + * gtk_label_set_max_width_chars: + * @label: a #GtkLabel + * @n_chars: the new desired maximal width, in characters. + * + * Sets the desired maximal width in characters of @label to @n_chars. + * + * Since: 2.6 + **/ +void +gtk_label_set_max_width_chars (GtkLabel *label, + gint n_chars) +{ + GtkLabelPrivate *priv; + + g_return_if_fail (GTK_IS_LABEL (label)); + + priv = GTK_LABEL_GET_PRIVATE (label); + + if (priv->max_width_chars != n_chars) + { + priv->max_width_chars = n_chars; + + g_object_notify (G_OBJECT (label), "max-width-chars"); + gtk_widget_queue_resize (GTK_WIDGET (label)); + } +} + +/** + * gtk_label_get_max_width_chars: + * @label: a #GtkLabel + * + * Retrieves the desired maximal width of @label, in characters. See + * gtk_label_set_width_chars(). + * + * Return value: the maximal width of the label in characters. + * + * Since: 2.6 + **/ +gint +gtk_label_get_max_width_chars (GtkLabel *label) +{ + g_return_val_if_fail (GTK_IS_LABEL (label), -1); + + return GTK_LABEL_GET_PRIVATE (label)->max_width_chars; +} + /** * gtk_label_set_line_wrap: * @label: a #GtkLabel @@ -1934,29 +2011,45 @@ gtk_label_size_request (GtkWidget *widget, } else pango_layout_get_extents (label->layout, NULL, &logical_rect); - - if (label->ellipsize || priv->width_chars > 0) + + if ((label->wrap || label->ellipsize || + priv->width_chars > 0 || priv->max_width_chars > 0) && + aux_info && aux_info->width > 0) + width += aux_info->width; + else if (label->ellipsize || priv->width_chars > 0 || priv->width_chars > 0) { PangoContext *context; PangoFontMetrics *metrics; - gint char_width; + gint char_width, digit_width, char_pixels, w; - /* The minimum size for ellipsized labels is ~ 3 chars */ context = pango_layout_get_context (label->layout); metrics = pango_context_get_metrics (context, widget->style->font_desc, NULL); char_width = pango_font_metrics_get_approximate_char_width (metrics); + digit_width = pango_font_metrics_get_approximate_digit_width (metrics); + char_pixels = MAX (char_width, digit_width); pango_font_metrics_unref (metrics); - width += (PANGO_PIXELS (char_width) * MAX (priv->width_chars, 3)); + if (priv->width_chars < 0) + { + PangoRectangle rect; + + pango_layout_set_width (label->layout, -1); + pango_layout_get_extents (label->layout, NULL, &rect); + + w = char_pixels * MAX (priv->max_width_chars, 3); + w = MIN (rect.width, w); + } + else + { + /* enforce minimum width for ellipsized labels at ~3 chars */ + w = char_pixels * MAX (priv->width_chars, 3); + } + + width += PANGO_PIXELS (w); } else - { - if (label->wrap && aux_info && aux_info->width > 0) - width += aux_info->width; - else - width += PANGO_PIXELS (logical_rect.width); - } + width += PANGO_PIXELS (logical_rect.width); if (priv->single_line_mode) { diff --git a/gtk/gtklabel.h b/gtk/gtklabel.h index c6e9407f84..b02f99bead 100644 --- a/gtk/gtklabel.h +++ b/gtk/gtklabel.h @@ -135,6 +135,9 @@ PangoEllipsizeMode gtk_label_get_ellipsize (GtkLabel *label); void gtk_label_set_width_chars (GtkLabel *label, gint n_chars); gint gtk_label_get_width_chars (GtkLabel *label); +void gtk_label_set_max_width_chars (GtkLabel *label, + gint n_chars); +gint gtk_label_get_max_width_chars (GtkLabel *label); void gtk_label_set_pattern (GtkLabel *label, const gchar *pattern); void gtk_label_set_line_wrap (GtkLabel *label,