X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gtk%2Fgtklabel.c;h=60ea406bc4fa26fbc1d656aaf3e9d429c6776291;hb=db76c77b819b1b31e19609bb1b30c85f22b5b482;hp=3a609380dc67236fa44a4e13b5fc5928abfd3666;hpb=dfd311497dda066e27b4b41ea920fa8e74cfc880;p=~andy%2Fgtk diff --git a/gtk/gtklabel.c b/gtk/gtklabel.c index 3a609380d..60ea406bc 100644 --- a/gtk/gtklabel.c +++ b/gtk/gtklabel.c @@ -59,6 +59,7 @@ typedef struct gint wrap_width; gint width_chars; gint max_width_chars; + gboolean mnemonics_visible; } GtkLabelPrivate; @@ -304,22 +305,22 @@ static void gtk_label_get_link_colors (GtkWidget *widget, static void emit_activate_link (GtkLabel *label, GtkLabelLink *link); -static void gtk_label_extended_layout_init (GtkExtendedLayoutIface *iface); - -static void gtk_label_get_desired_width (GtkExtendedLayout *layout, - gint *minimum_size, - gint *natural_size); -static void gtk_label_get_desired_height (GtkExtendedLayout *layout, - gint *minimum_size, - gint *natural_size); -static void gtk_label_get_width_for_height (GtkExtendedLayout *layout, - gint height, - gint *minimum_width, - gint *natural_width); -static void gtk_label_get_height_for_width (GtkExtendedLayout *layout, - gint width, - gint *minimum_height, - gint *natural_height); +static void gtk_label_extended_layout_init (GtkExtendedLayoutIface *iface); +static gboolean gtk_label_is_height_for_width (GtkExtendedLayout *layout); +static void gtk_label_get_desired_width (GtkExtendedLayout *layout, + gint *minimum_size, + gint *natural_size); +static void gtk_label_get_desired_height (GtkExtendedLayout *layout, + gint *minimum_size, + gint *natural_size); +static void gtk_label_get_width_for_height (GtkExtendedLayout *layout, + gint height, + gint *minimum_width, + gint *natural_width); +static void gtk_label_get_height_for_width (GtkExtendedLayout *layout, + gint width, + gint *minimum_height, + gint *natural_height); static GQuark quark_angle = 0; @@ -664,12 +665,13 @@ gtk_label_class_init (GtkLabelClass *class) /** * GtkLabel:width-chars: - * + * * 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 - * #GtkLabel:max-width-chars property is ignored. + * -1, the width will be calculated automatically. + * + * See the section on text layout + * for details of how #GtkLabel:width-chars and #GtkLabel:max-width-chars + * determine the width of ellipsized and wrapped labels. * * Since: 2.6 **/ @@ -726,11 +728,12 @@ gtk_label_class_init (GtkLabelClass *class) * GtkLabel:max-width-chars: * * The desired maximum width 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 #GtkLabel:width-chars property is set to a positive - * value, then the "max-width-chars" property is ignored. - * + * is set to -1, the width will be calculated automatically. + * + * See the section on text layout + * for details of how #GtkLabel:width-chars and #GtkLabel:max-width-chars + * determine the width of ellipsized and wrapped labels. + * * Since: 2.6 **/ g_object_class_install_property (gobject_class, @@ -3027,7 +3030,6 @@ get_label_width (GtkLabel *label, } else { - /* XXX Do something about width_chars/max_width_chars when no ellipsize/wrap is set */ *minimum = text_width; *natural = *minimum; } @@ -3062,7 +3064,7 @@ get_label_wrap_width (GtkLabel *label) if (priv->wrap_width < 0) { - if (priv->width_chars > 0 || priv->max_width_chars > 0) + if (priv->width_chars > 0) { PangoLayout *layout; PangoContext *context; @@ -3086,21 +3088,14 @@ get_label_wrap_width (GtkLabel *label) text_width = rect.width; - if (priv->max_width_chars < 0) - { - priv->wrap_width = PANGO_PIXELS (MAX (text_width, char_pixels * priv->width_chars)); - } - else - { - priv->wrap_width = PANGO_PIXELS (MIN (text_width, char_pixels * priv->max_width_chars)); - } + priv->wrap_width = PANGO_PIXELS (MAX (text_width, char_pixels * priv->width_chars)); } else { PangoLayout *layout; layout = gtk_widget_create_pango_layout (GTK_WIDGET (label), - "This long string gives a good enough length for any line to have."); + "This string is just about long enough."); pango_layout_get_size (layout, &priv->wrap_width, NULL); g_object_unref (layout); } @@ -3195,7 +3190,7 @@ gtk_label_ensure_layout (GtkLabel *label, gboolean guess_wrap_width) if (aux_width > 0) pango_layout_set_width (label->layout, aux_width * PANGO_SCALE); else if (guess_wrap_width == FALSE && - widget->allocation.width > 1) + widget->allocation.width > 1 && widget->allocation.height > 1) { if (angle == 90 || angle == 270) width = widget->allocation.height - label->misc.ypad * 2; @@ -3286,27 +3281,37 @@ get_single_line_height (GtkWidget *widget, return ascent + descent; } - - static void gtk_label_extended_layout_init (GtkExtendedLayoutIface *iface) { + iface->is_height_for_width = gtk_label_is_height_for_width; iface->get_desired_width = gtk_label_get_desired_width; iface->get_desired_height = gtk_label_get_desired_height; iface->get_width_for_height = gtk_label_get_width_for_height; iface->get_height_for_width = gtk_label_get_height_for_width; } +static gboolean +gtk_label_is_height_for_width (GtkExtendedLayout *layout) +{ + GtkLabel *label = GTK_LABEL (layout); + gdouble angle = gtk_label_get_angle (label); + + if (angle == 90 || angle == 270) + return FALSE; + + return TRUE; +} static void get_size_for_allocation (GtkLabel *label, - GtkOrientation orientation, - gint allocation, - gint *minimum_size, - gint *natural_size) + GtkOrientation orientation, + gint allocation, + gint *minimum_size, + gint *natural_size) { PangoLayout *layout; - GtkWidgetAuxInfo *aux_info = + GtkWidgetAuxInfo *aux_info = _gtk_widget_get_aux_info (GTK_WIDGET (label), FALSE); gint aux_size; gint text_height; @@ -3317,9 +3322,9 @@ get_size_for_allocation (GtkLabel *label, if (aux_info) { if (orientation == GTK_ORIENTATION_HORIZONTAL) - aux_size = aux_info->width; + aux_size = aux_info->width; else - aux_size = aux_info->height; + aux_size = aux_info->height; } else aux_size = 0; @@ -3342,7 +3347,7 @@ get_size_for_allocation (GtkLabel *label, static void gtk_label_get_desired_size (GtkExtendedLayout *layout, - GtkOrientation orientation, + GtkOrientation orientation, gint *minimum_size, gint *natural_size) { @@ -3351,7 +3356,7 @@ gtk_label_get_desired_size (GtkExtendedLayout *layout, PangoRectangle natural_rect; gdouble angle; - /* "width-chars" Hard-coded minimum width: + /* "width-chars" Hard-coded minimum width: * - minimum size should be MAX (width-chars, strlen ("...")); * - natural size should be MAX (width-chars, strlen (label->text)); * @@ -3367,7 +3372,6 @@ gtk_label_get_desired_size (GtkExtendedLayout *layout, gtk_label_clear_layout (label); gtk_label_ensure_layout (label, TRUE); - angle = gtk_label_get_angle (label); /* Start off with the pixel extents of the rendered layout */ @@ -3378,7 +3382,7 @@ gtk_label_get_desired_size (GtkExtendedLayout *layout, required_rect.height = get_single_line_height (GTK_WIDGET (label), label->layout); natural_rect = required_rect; - + /* Calculate text width itself based on GtkLabel property rules */ get_label_width (label, &required_rect.width, &natural_rect.width); @@ -3398,20 +3402,21 @@ gtk_label_get_desired_size (GtkExtendedLayout *layout, pango_matrix_transform_rectangle (matrix, &required_rect); pango_matrix_transform_rectangle (matrix, &natural_rect); - /* Bump the natural size incase of ellipsize to ensure pango has enough space in the angles - * (note, we could alternatively set the layout to not ellipsize when we know we have been - * allocated our full natural size, or it may be that pango needs a fix here). + /* Bump the natural size in case of ellipsize to ensure pango has + * enough space in the angles (note, we could alternatively set the + * layout to not ellipsize when we know we have been allocated our + * full natural size, or it may be that pango needs a fix here). */ if (label->ellipsize && angle != 0 && angle != 90 && angle != 180 && angle != 270 && angle != 360) - { - /* For some reason we only need this at about 110 degrees, and only - * when gaining in height - */ - natural_rect.height += ROTATION_ELLIPSIZE_PADDING * 2 * PANGO_SCALE; - natural_rect.width += ROTATION_ELLIPSIZE_PADDING * 2 * PANGO_SCALE; - } + { + /* For some reason we only need this at about 110 degrees, and only + * when gaining in height + */ + natural_rect.height += ROTATION_ELLIPSIZE_PADDING * 2 * PANGO_SCALE; + natural_rect.width += ROTATION_ELLIPSIZE_PADDING * 2 * PANGO_SCALE; + } } - + required_rect.width = PANGO_PIXELS_CEIL (required_rect.width); required_rect.height = PANGO_PIXELS_CEIL (required_rect.height); @@ -3420,41 +3425,56 @@ gtk_label_get_desired_size (GtkExtendedLayout *layout, if (orientation == GTK_ORIENTATION_HORIZONTAL) { - /* Note, we cant use get_size_for_allocation() when rotating ellipsize labels. + /* Note, we cant use get_size_for_allocation() when rotating + * ellipsized labels. */ - if (!(label->ellipsize && label->have_transform) && (angle == 90 || angle == 270)) - { - /* Doing a h4w request on a rotated label here, return the required width for the minimum height. */ - get_size_for_allocation (label, GTK_ORIENTATION_VERTICAL, - required_rect.height, minimum_size, natural_size); + if (!(label->ellipsize && label->have_transform) && + (angle == 90 || angle == 270)) + { + /* Doing a h4w request on a rotated label here, return the + * required width for the minimum height. + */ + get_size_for_allocation (label, + GTK_ORIENTATION_VERTICAL, + required_rect.height, + minimum_size, natural_size); - } + } else - { - /* Normal desired width */ - *minimum_size = required_rect.width; - *natural_size = natural_rect.width; - } - + { + /* Normal desired width */ + *minimum_size = required_rect.width; + *natural_size = natural_rect.width; + } + *minimum_size += label->misc.xpad * 2; *natural_size += label->misc.xpad * 2; - } + } else /* GTK_ORIENTATION_VERTICAL */ { - /* Note, we cant use get_size_for_allocation() when rotating ellipsize labels. + /* Note, we cant use get_size_for_allocation() when rotating + * ellipsized labels. */ - if (angle == 90 || angle == 270 || (label->ellipsize && label->have_transform)) - { - /* A vertically rotated label does w4h, so return the base desired height (text length) */ - *minimum_size = required_rect.height; - *natural_size = natural_rect.height; - } + if (!(label->ellipsize && label->have_transform) && + (angle == 0 || angle == 180)) + { + /* Doing a w4h request on a label here, return the required + * height for the minimum width. + */ + get_size_for_allocation (label, + GTK_ORIENTATION_HORIZONTAL, + required_rect.width, + minimum_size, natural_size); + } else - { - /* Doing a w4h request on a label here, return the required height for the minimum width. */ - get_size_for_allocation (label, GTK_ORIENTATION_HORIZONTAL, - required_rect.width, minimum_size, natural_size); - } + { + /* A vertically rotated label does w4h, so return the base + * desired height (text length) + */ + *minimum_size = required_rect.height; + *natural_size = natural_rect.height; + } + *minimum_size += label->misc.ypad * 2; *natural_size += label->misc.ypad * 2; } @@ -3473,18 +3493,22 @@ gtk_label_get_desired_size (GtkExtendedLayout *layout, static void gtk_label_get_desired_width (GtkExtendedLayout *layout, - gint *minimum_size, - gint *natural_size) + gint *minimum_size, + gint *natural_size) { - gtk_label_get_desired_size (layout, GTK_ORIENTATION_HORIZONTAL, minimum_size, natural_size); + gtk_label_get_desired_size (layout, + GTK_ORIENTATION_HORIZONTAL, + minimum_size, natural_size); } static void gtk_label_get_desired_height (GtkExtendedLayout *layout, - gint *minimum_size, - gint *natural_size) + gint *minimum_size, + gint *natural_size) { - gtk_label_get_desired_size (layout, GTK_ORIENTATION_VERTICAL, minimum_size, natural_size); + gtk_label_get_desired_size (layout, + GTK_ORIENTATION_VERTICAL, + minimum_size, natural_size); } static void @@ -3499,17 +3523,17 @@ gtk_label_get_width_for_height (GtkExtendedLayout *layout, if (label->wrap && (angle == 90 || angle == 270)) { if (label->wrap) - gtk_label_clear_layout (label); + gtk_label_clear_layout (label); - get_size_for_allocation (label, GTK_ORIENTATION_VERTICAL, - MAX (1, height - (label->misc.ypad * 2)), - minimum_width, natural_width); + get_size_for_allocation (label, GTK_ORIENTATION_VERTICAL, + MAX (1, height - (label->misc.ypad * 2)), + minimum_width, natural_width); if (minimum_width) - minimum_width += label->misc.xpad * 2; + *minimum_width += label->misc.xpad * 2; if (natural_width) - natural_width += label->misc.xpad * 2; + *natural_width += label->misc.xpad * 2; } else GTK_EXTENDED_LAYOUT_GET_IFACE (layout)->get_desired_width (layout, minimum_width, natural_width); @@ -3527,17 +3551,17 @@ gtk_label_get_height_for_width (GtkExtendedLayout *layout, if (label->wrap && (angle == 0 || angle == 180 || angle == 360)) { if (label->wrap) - gtk_label_clear_layout (label); + gtk_label_clear_layout (label); - get_size_for_allocation (label, GTK_ORIENTATION_HORIZONTAL, - MAX (1, width - label->misc.xpad * 2), - minimum_height, natural_height); + get_size_for_allocation (label, GTK_ORIENTATION_HORIZONTAL, + MAX (1, width - label->misc.xpad * 2), + minimum_height, natural_height); if (minimum_height) - minimum_height += label->misc.ypad * 2; + *minimum_height += label->misc.ypad * 2; if (natural_height) - natural_height += label->misc.ypad * 2; + *natural_height += label->misc.ypad * 2; } else GTK_EXTENDED_LAYOUT_GET_IFACE (layout)->get_desired_height (layout, minimum_height, natural_height); @@ -3553,8 +3577,8 @@ gtk_label_size_allocate (GtkWidget *widget, GTK_WIDGET_CLASS (gtk_label_parent_class)->size_allocate (widget, allocation); - /* The layout may have been recently cleared in get_size_for_orientation(), but the - * width at that point may not be the same as the allocated width + /* The layout may have been recently cleared in get_size_for_orientation(), + * but the width at that point may not be the same as the allocated width */ if (label->wrap) gtk_label_clear_layout (label); @@ -3564,7 +3588,7 @@ gtk_label_size_allocate (GtkWidget *widget, if (label->ellipsize) { if (label->layout) - { + { PangoRectangle logical; PangoRectangle bounds;