diff options
author | Matthias Clasen <mclasen@redhat.com> | 2021-12-20 15:49:05 +0000 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2021-12-20 15:49:05 +0000 |
commit | 69edf17c2a31cdd84907b87cf4f34c2f6d960c2b (patch) | |
tree | 0c4d0c120761cff6af1a937769967b71857fc8c7 | |
parent | d91a4ad1ddf2df59886016657c6ce012a66dec16 (diff) | |
parent | 981ed22dff12f5c356faa67886a48d1b2ab18a84 (diff) | |
download | gtk+-69edf17c2a31cdd84907b87cf4f34c2f6d960c2b.tar.gz |
Merge branch 'wip/otte/wrapping-is-natural' into 'main'
label: Add gtk_label_set_natural_wrap_mode()
See merge request GNOME/gtk!4267
-rw-r--r-- | gtk/gtkenums.h | 25 | ||||
-rw-r--r-- | gtk/gtklabel.c | 106 | ||||
-rw-r--r-- | gtk/gtklabel.h | 5 | ||||
-rw-r--r-- | testsuite/reftests/label-wrap-word-char-natural-size.ref.ui | 14 | ||||
-rw-r--r-- | testsuite/reftests/label-wrap-word-char-natural-size.ui | 17 |
5 files changed, 152 insertions, 15 deletions
diff --git a/gtk/gtkenums.h b/gtk/gtkenums.h index d356a9154e..69faa56db8 100644 --- a/gtk/gtkenums.h +++ b/gtk/gtkenums.h @@ -286,6 +286,31 @@ typedef enum } 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. * @GTK_SCROLL_PAGES: Scroll by pages. diff --git a/gtk/gtklabel.c b/gtk/gtklabel.c index 9af80f43a9..1f019fadaa 100644 --- a/gtk/gtklabel.c +++ b/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", @@ -2385,6 +2406,27 @@ gtk_label_class_init (GtkLabelClass *class) 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) * * Whether the label text can be selected with the mouse. @@ -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) { diff --git a/gtk/gtklabel.h b/gtk/gtklabel.h index 36441a5fe9..4a42a4ba32 100644 --- a/gtk/gtklabel.h +++ b/gtk/gtklabel.h @@ -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); diff --git a/testsuite/reftests/label-wrap-word-char-natural-size.ref.ui b/testsuite/reftests/label-wrap-word-char-natural-size.ref.ui index b8a08efc62..405064420c 100644 --- a/testsuite/reftests/label-wrap-word-char-natural-size.ref.ui +++ b/testsuite/reftests/label-wrap-word-char-natural-size.ref.ui @@ -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> diff --git a/testsuite/reftests/label-wrap-word-char-natural-size.ui b/testsuite/reftests/label-wrap-word-char-natural-size.ui index 929e5a3089..f70099651e 100644 --- a/testsuite/reftests/label-wrap-word-char-natural-size.ui +++ b/testsuite/reftests/label-wrap-word-char-natural-size.ui @@ -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> |