diff options
author | Matthias Clasen <mclasen@redhat.com> | 2023-04-29 10:40:20 -0400 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2023-04-29 10:42:29 -0400 |
commit | ebd4f55335fdbf0c69fc4492b945f8f4ff007ea9 (patch) | |
tree | 8971aebf830c76974bb9f9ee1c4b44eae288ace0 | |
parent | a8a0850b64a29ddfbb1798451759ec63d47db301 (diff) | |
download | gtk+-label-baseline-row.tar.gz |
label: Allow picking a baseline rowlabel-baseline-row
Add a property that specifies which line in a multi-line
label to align to the baseline.
-rw-r--r-- | gtk/gtklabel.c | 104 | ||||
-rw-r--r-- | gtk/gtklabel.h | 6 |
2 files changed, 105 insertions, 5 deletions
diff --git a/gtk/gtklabel.c b/gtk/gtklabel.c index ecb48a8d07..ee8b462aa2 100644 --- a/gtk/gtklabel.c +++ b/gtk/gtklabel.c @@ -284,6 +284,8 @@ struct _GtkLabel guint mnemonic_keyval; + unsigned int baseline_row; + int width_chars; int max_width_chars; int lines; @@ -381,6 +383,7 @@ enum { PROP_0, PROP_LABEL, PROP_ATTRIBUTES, + PROP_BASELINE_ROW, PROP_USE_MARKUP, PROP_USE_UNDERLINE, PROP_JUSTIFY, @@ -477,6 +480,9 @@ gtk_label_set_property (GObject *object, case PROP_ATTRIBUTES: gtk_label_set_attributes (self, g_value_get_boxed (value)); break; + case PROP_BASELINE_ROW: + gtk_label_set_baseline_row (self, g_value_get_uint (value)); + break; case PROP_USE_MARKUP: gtk_label_set_use_markup (self, g_value_get_boolean (value)); break; @@ -550,6 +556,9 @@ gtk_label_get_property (GObject *object, case PROP_ATTRIBUTES: g_value_set_boxed (value, self->attrs); break; + case PROP_BASELINE_ROW: + g_value_set_uint (value, self->baseline_row); + break; case PROP_USE_MARKUP: g_value_set_boolean (value, self->use_markup); break; @@ -1091,6 +1100,31 @@ get_default_widths (GtkLabel *self, } } +static int +get_layout_baseline (GtkLabel *self, + PangoLayout *layout) +{ + PangoLayoutIter *iter; + int baseline; + unsigned int lineno; + + lineno = 0; + iter = pango_layout_get_iter (layout); + do + { + if (lineno == self->baseline_row) + break; + + lineno++; + } + while (pango_layout_iter_next_line (iter)); + + baseline = pango_layout_iter_get_baseline (iter); + pango_layout_iter_free (iter); + + return baseline; +} + static void get_static_size (GtkLabel *self, GtkOrientation orientation, @@ -1126,7 +1160,7 @@ get_static_size (GtkLabel *self, else { pango_layout_get_size (layout, NULL, minimum); - *minimum_baseline = pango_layout_get_baseline (layout); + *minimum_baseline = get_layout_baseline (self, layout); *natural = *minimum; *natural_baseline = *minimum_baseline; @@ -1151,7 +1185,7 @@ get_height_for_width (GtkLabel *self, /* Minimum height is assuming infinite width */ layout = gtk_label_get_measuring_layout (self, NULL, -1); pango_layout_get_size (layout, NULL, minimum_height); - baseline = pango_layout_get_baseline (layout); + baseline = get_layout_baseline (self, layout); *minimum_baseline = baseline; /* Natural height is assuming natural width */ @@ -1159,7 +1193,7 @@ get_height_for_width (GtkLabel *self, layout = gtk_label_get_measuring_layout (self, layout, natural_width); pango_layout_get_size (layout, NULL, natural_height); - baseline = pango_layout_get_baseline (layout); + baseline = get_layout_baseline (self, layout); *natural_baseline = baseline; } else @@ -1172,7 +1206,7 @@ get_height_for_width (GtkLabel *self, *minimum_height = text_height; *natural_height = text_height; - baseline = pango_layout_get_baseline (layout); + baseline = get_layout_baseline (self, layout); *minimum_baseline = baseline; *natural_baseline = baseline; } @@ -1338,7 +1372,7 @@ get_layout_location (GtkLabel *self, baseline = gtk_widget_get_baseline (widget); if (baseline != -1) { - int layout_baseline = pango_layout_get_baseline (self->layout) / PANGO_SCALE; + int layout_baseline = get_layout_baseline (self, self->layout) / PANGO_SCALE; /* yalign is 0 because we can't support yalign while baseline aligning */ y = baseline - layout_baseline; } @@ -2597,6 +2631,21 @@ gtk_label_class_init (GtkLabelClass *class) PANGO_TYPE_TAB_ARRAY, GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY); + /** + * GtkLabel:baseline-row: (attributes org.gtk.Property.get=gtk_label_get_baseline_row org.gtk.Property.set=gtk_label_set_baseline_row) + * + * The line in the text to which the baseline is aligned. + * + * If this number is bigger than the the number of lines in the formatted + * text, the baseline is aligned to the last line. + * + * Since: 4.12 + */ + label_props[PROP_BASELINE_ROW] = + g_param_spec_uint ("baseline-row", NULL, NULL, + 0, G_MAXUINT, 0, + GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY); + g_object_class_install_properties (gobject_class, NUM_PROPERTIES, label_props); /** @@ -6025,3 +6074,48 @@ gtk_label_get_tabs (GtkLabel *self) return self->tabs ? pango_tab_array_copy (self->tabs) : NULL; } + +/** + * gtk_label_set_baseline_row: + * @self: a `GtkLabel` + * @baseline_row: the row to align with the baseline + * + * Sets the row to align with the baseline. + * + * This is only relevant if the label is inside a container + * that is doing baseline alignment. + * + * Since: 4.12 + */ +void +gtk_label_set_baseline_row (GtkLabel *self, + unsigned int baseline_row) +{ + g_return_if_fail (GTK_IS_LABEL (self)); + + if (self->baseline_row == baseline_row) + return; + + self->baseline_row = baseline_row; + + g_object_notify_by_pspec (G_OBJECT (self), label_props[PROP_BASELINE_ROW]); + gtk_widget_queue_resize (GTK_WIDGET (self)); +} + +/** + * gtk_label_get_baseline_row: + * @self: a `GtkLabel` + * + * Gets the row to align with the baseline. + * + * Returns: the row to align with the baseline + * + * Since: 4.12 + */ +unsigned int +gtk_label_get_baseline_row (GtkLabel *self) +{ + g_return_val_if_fail (GTK_IS_LABEL (self), 0); + + return self->baseline_row; +} diff --git a/gtk/gtklabel.h b/gtk/gtklabel.h index c27b60b5f9..dd182473ff 100644 --- a/gtk/gtklabel.h +++ b/gtk/gtklabel.h @@ -183,6 +183,12 @@ void gtk_label_set_tabs (GtkLabel *self, GDK_AVAILABLE_IN_4_8 PangoTabArray * gtk_label_get_tabs (GtkLabel *self); +GDK_AVAILABLE_IN_4_12 +void gtk_label_set_baseline_row (GtkLabel *self, + unsigned int baseline_row); + +GDK_AVAILABLE_IN_4_12 +unsigned int gtk_label_get_baseline_row (GtkLabel *self); G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkLabel, g_object_unref) |