forked from AuroraMiddleware/gtk
Merge branch 'wip/otte/wrapping-is-natural' into 'main'
label: Add gtk_label_set_natural_wrap_mode() See merge request GNOME/gtk!4267
This commit is contained in:
commit
69edf17c2a
@ -285,6 +285,31 @@ typedef enum
|
||||
GTK_MOVEMENT_HORIZONTAL_PAGES
|
||||
} GtkMovementStep;
|
||||
|
||||
/**
|
||||
* GtkNaturalWrapMode:
|
||||
* @GTK_NATURAL_WRAP_INHERIT: Inherit the minimum size request.
|
||||
* In particular, this should be used with %PANGO_WRAP_CHAR.
|
||||
* @GTK_NATURAL_WRAP_NONE: Try not to wrap the text. This mode is the
|
||||
* closest to GTK3's behavior but can lead to a wide label leaving
|
||||
* lots of empty space below the text.
|
||||
* @GTK_NATURAL_WRAP_WORD: Attempt to wrap at word boundaries. This
|
||||
* is useful in particular when using %PANGO_WRAP_WORD_CHAR as the
|
||||
* wrap mode.
|
||||
*
|
||||
* Options for selecting a different wrap mode for natural size
|
||||
* requests.
|
||||
*
|
||||
* See for example the [property@Gtk.Label:natural-wrap-mode] property.
|
||||
*
|
||||
* Since: 4.6
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
GTK_NATURAL_WRAP_INHERIT,
|
||||
GTK_NATURAL_WRAP_NONE,
|
||||
GTK_NATURAL_WRAP_WORD
|
||||
} GtkNaturalWrapMode;
|
||||
|
||||
/**
|
||||
* GtkScrollStep:
|
||||
* @GTK_SCROLL_STEPS: Scroll in steps.
|
||||
|
106
gtk/gtklabel.c
106
gtk/gtklabel.c
@ -272,6 +272,7 @@ struct _GtkLabel
|
||||
guint ellipsize : 3;
|
||||
guint use_markup : 1;
|
||||
guint wrap_mode : 3;
|
||||
guint natural_wrap_mode : 3;
|
||||
guint single_line_mode : 1;
|
||||
guint in_click : 1;
|
||||
guint track_links : 1;
|
||||
@ -380,6 +381,7 @@ enum {
|
||||
PROP_JUSTIFY,
|
||||
PROP_WRAP,
|
||||
PROP_WRAP_MODE,
|
||||
PROP_NATURAL_WRAP_MODE,
|
||||
PROP_SELECTABLE,
|
||||
PROP_MNEMONIC_KEYVAL,
|
||||
PROP_MNEMONIC_WIDGET,
|
||||
@ -484,6 +486,9 @@ gtk_label_set_property (GObject *object,
|
||||
case PROP_WRAP_MODE:
|
||||
gtk_label_set_wrap_mode (self, g_value_get_enum (value));
|
||||
break;
|
||||
case PROP_NATURAL_WRAP_MODE:
|
||||
gtk_label_set_natural_wrap_mode (self, g_value_get_enum (value));
|
||||
break;
|
||||
case PROP_SELECTABLE:
|
||||
gtk_label_set_selectable (self, g_value_get_boolean (value));
|
||||
break;
|
||||
@ -551,6 +556,9 @@ gtk_label_get_property (GObject *object,
|
||||
case PROP_WRAP_MODE:
|
||||
g_value_set_enum (value, self->wrap_mode);
|
||||
break;
|
||||
case PROP_NATURAL_WRAP_MODE:
|
||||
g_value_set_enum (value, self->natural_wrap_mode);
|
||||
break;
|
||||
case PROP_SELECTABLE:
|
||||
g_value_set_boolean (value, gtk_label_get_selectable (self));
|
||||
break;
|
||||
@ -604,6 +612,7 @@ gtk_label_init (GtkLabel *self)
|
||||
self->jtype = GTK_JUSTIFY_LEFT;
|
||||
self->wrap = FALSE;
|
||||
self->wrap_mode = PANGO_WRAP_WORD;
|
||||
self->natural_wrap_mode = GTK_NATURAL_WRAP_INHERIT;
|
||||
self->ellipsize = PANGO_ELLIPSIZE_NONE;
|
||||
|
||||
self->use_underline = FALSE;
|
||||
@ -1218,8 +1227,6 @@ get_width_for_height (GtkLabel *self,
|
||||
gtk_label_ensure_layout (self);
|
||||
layout = pango_layout_copy (self->layout);
|
||||
pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_NONE);
|
||||
if (self->wrap_mode == PANGO_WRAP_WORD_CHAR)
|
||||
pango_layout_set_wrap (layout, PANGO_WRAP_WORD);
|
||||
|
||||
/* binary search for the smallest width where the height doesn't
|
||||
* eclipse the given height */
|
||||
@ -1228,8 +1235,19 @@ get_width_for_height (GtkLabel *self,
|
||||
pango_layout_set_width (layout, -1);
|
||||
pango_layout_get_size (layout, &max, NULL);
|
||||
|
||||
*natural_width = my_pango_layout_get_width_for_height (layout, height, min, max);
|
||||
/* first, do natural width */
|
||||
if (self->natural_wrap_mode == GTK_NATURAL_WRAP_NONE)
|
||||
{
|
||||
*natural_width = max;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (self->natural_wrap_mode == GTK_NATURAL_WRAP_WORD)
|
||||
pango_layout_set_wrap (layout, PANGO_WRAP_WORD);
|
||||
*natural_width = my_pango_layout_get_width_for_height (layout, height, min, max);
|
||||
}
|
||||
|
||||
/* then, do minimum width */
|
||||
if (self->ellipsize != PANGO_ELLIPSIZE_NONE)
|
||||
{
|
||||
g_object_unref (layout);
|
||||
@ -1237,14 +1255,14 @@ get_width_for_height (GtkLabel *self,
|
||||
pango_layout_get_size (layout, minimum_width, NULL);
|
||||
*minimum_width = MAX (*minimum_width, minimum_default);
|
||||
}
|
||||
else if (self->wrap_mode == PANGO_WRAP_WORD_CHAR)
|
||||
else if (self->natural_wrap_mode == GTK_NATURAL_WRAP_INHERIT)
|
||||
{
|
||||
pango_layout_set_wrap (layout, PANGO_WRAP_WORD_CHAR);
|
||||
*minimum_width = my_pango_layout_get_width_for_height (layout, height, min, *natural_width);
|
||||
*minimum_width = *natural_width;
|
||||
}
|
||||
else
|
||||
{
|
||||
*minimum_width = *natural_width;
|
||||
pango_layout_set_wrap (layout, self->wrap_mode);
|
||||
*minimum_width = my_pango_layout_get_width_for_height (layout, height, min, *natural_width);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2375,6 +2393,9 @@ gtk_label_class_init (GtkLabelClass *class)
|
||||
* This only affects the formatting if line wrapping is on (see the
|
||||
* [property@Gtk.Label:wrap] property). The default is %PANGO_WRAP_WORD,
|
||||
* which means wrap on word boundaries.
|
||||
*
|
||||
* For sizing behavior, also consider the [property@Gtk.Label:natural-wrap-mode]
|
||||
* property.
|
||||
*/
|
||||
label_props[PROP_WRAP_MODE] =
|
||||
g_param_spec_enum ("wrap-mode",
|
||||
@ -2384,6 +2405,27 @@ gtk_label_class_init (GtkLabelClass *class)
|
||||
PANGO_WRAP_WORD,
|
||||
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
/**
|
||||
* GtkLabel:natural-wrap-mode: (attributes org.gtk.Property.get=gtk_label_get_natural_wrap_mode org.gtk.Property.set=gtk_label_set_natural_wrap_mode)
|
||||
*
|
||||
* Select the line wrapping for the natural size request.
|
||||
*
|
||||
* This only affects the natural size requested. For the actual wrapping used,
|
||||
* see the [property@Gtk.Label:wrap-mode] property.
|
||||
*
|
||||
* The default is %GTK_NATURAL_WRAP_INHERIT, which inherits the behavior of the
|
||||
* [property@Gtk.Label:wrap-mode] property.
|
||||
*
|
||||
* Since: 4.6
|
||||
*/
|
||||
label_props[PROP_NATURAL_WRAP_MODE] =
|
||||
g_param_spec_enum ("natural-wrap-mode",
|
||||
P_("Natrural wrap mode"),
|
||||
P_("If wrap is set, controls linewrapping for natural size requests"),
|
||||
GTK_TYPE_NATURAL_WRAP_MODE,
|
||||
GTK_NATURAL_WRAP_INHERIT,
|
||||
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
/**
|
||||
* GtkLabel:selectable: (attributes org.gtk.Property.get=gtk_label_get_selectable og.gtk.Property.set=gtk_label_set_selectable)
|
||||
*
|
||||
@ -3998,6 +4040,9 @@ gtk_label_get_wrap (GtkLabel *self)
|
||||
* This only affects the label if line wrapping is on. (See
|
||||
* [method@Gtk.Label.set_wrap]) The default is %PANGO_WRAP_WORD
|
||||
* which means wrap on word boundaries.
|
||||
*
|
||||
* For sizing behavior, also consider the [property@Gtk.Label:natural-wrap-mode]
|
||||
* property.
|
||||
*/
|
||||
void
|
||||
gtk_label_set_wrap_mode (GtkLabel *self,
|
||||
@ -4032,6 +4077,53 @@ gtk_label_get_wrap_mode (GtkLabel *self)
|
||||
return self->wrap_mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_label_set_natural_wrap_mode: (attributes org.gtk.Method.set_property=natural-wrap-mode)
|
||||
* @self: a `GtkLabel`
|
||||
* @wrap_mode: the line wrapping mode
|
||||
*
|
||||
* Select the line wrapping for the natural size request.
|
||||
*
|
||||
* This only affects the natural size requested, for the actual wrapping used,
|
||||
* see the [property@Gtk.Label:wrap-mode] property.
|
||||
*
|
||||
* Since: 4.6
|
||||
*/
|
||||
void
|
||||
gtk_label_set_natural_wrap_mode (GtkLabel *self,
|
||||
GtkNaturalWrapMode wrap_mode)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_LABEL (self));
|
||||
|
||||
if (self->natural_wrap_mode != wrap_mode)
|
||||
{
|
||||
self->natural_wrap_mode = wrap_mode;
|
||||
g_object_notify_by_pspec (G_OBJECT (self), label_props[PROP_NATURAL_WRAP_MODE]);
|
||||
|
||||
gtk_widget_queue_resize (GTK_WIDGET (self));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_label_get_natural_wrap_mode: (attributes org.gtk.Method.get_property=natural-wrap-mode)
|
||||
* @self: a `GtkLabel`
|
||||
*
|
||||
* Returns line wrap mode used by the label.
|
||||
*
|
||||
* See [method@Gtk.Label.set_natural_wrap_mode].
|
||||
*
|
||||
* Returns: the natural line wrap mode
|
||||
*
|
||||
* Since: 4.6
|
||||
*/
|
||||
GtkNaturalWrapMode
|
||||
gtk_label_get_natural_wrap_mode (GtkLabel *self)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_LABEL (self), PANGO_WRAP_CHAR);
|
||||
|
||||
return self->natural_wrap_mode;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_label_clear_layout (GtkLabel *self)
|
||||
{
|
||||
|
@ -122,6 +122,11 @@ void gtk_label_set_wrap_mode (GtkLabel *self,
|
||||
PangoWrapMode wrap_mode);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
PangoWrapMode gtk_label_get_wrap_mode (GtkLabel *self);
|
||||
GDK_AVAILABLE_IN_4_6
|
||||
void gtk_label_set_natural_wrap_mode (GtkLabel *self,
|
||||
GtkNaturalWrapMode wrap_mode);
|
||||
GDK_AVAILABLE_IN_4_6
|
||||
GtkNaturalWrapMode gtk_label_get_natural_wrap_mode(GtkLabel *self);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_label_set_selectable (GtkLabel *self,
|
||||
gboolean setting);
|
||||
|
@ -1,21 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<object class="GtkWindow">
|
||||
<property name="default-width">300</property>
|
||||
<property name="default-width">600</property>
|
||||
<property name="default-height">300</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">center</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">two
|
||||
<property name="label">lots
|
||||
of
|
||||
lines</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">unwrapped</property>
|
||||
<property name="label">unwrappable
|
||||
words</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">single line of text</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
@ -1,23 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<object class="GtkWindow">
|
||||
<property name="default-width">300</property>
|
||||
<property name="default-width">600</property>
|
||||
<property name="default-height">300</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">center</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">two
|
||||
<property name="label">lots
|
||||
of
|
||||
lines</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">unwrapped</property>
|
||||
<property name="label">unwrappable words</property>
|
||||
<property name="wrap">1</property>
|
||||
<property name="wrap-mode">word-char</property>
|
||||
<property name="natural-wrap-mode">word</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">single line of text</property>
|
||||
<property name="wrap">1</property>
|
||||
<property name="wrap-mode">word-char</property>
|
||||
<property name="natural-wrap-mode">none</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
Loading…
Reference in New Issue
Block a user