From d05191a010bcd9871b0155a785989192967c692b Mon Sep 17 00:00:00 2001 From: Cosimo Cecchi Date: Sun, 2 Sep 2012 19:14:04 -0400 Subject: [PATCH] entry: fix requisition width/height to use the current pango layout This way, we can ensure that width/height changes due to the use of gtk_entry_set_attributes() are correctly reflected in the size request. https://bugzilla.gnome.org/show_bug.cgi?id=683168 --- gtk/gtkentry.c | 8 +++-- gtk/gtkspinbutton.c | 81 ++++++++++++++++++++------------------------- 2 files changed, 40 insertions(+), 49 deletions(-) diff --git a/gtk/gtkentry.c b/gtk/gtkentry.c index ecbfd201e9..0c637de275 100644 --- a/gtk/gtkentry.c +++ b/gtk/gtkentry.c @@ -3273,7 +3273,9 @@ gtk_entry_get_preferred_height (GtkWidget *widget, GtkStateFlags state; PangoContext *context; gint height; + PangoLayout *layout; + layout = gtk_entry_ensure_layout (entry, TRUE); context = gtk_widget_get_pango_context (widget); style_context = gtk_widget_get_style_context (widget); @@ -3285,12 +3287,12 @@ gtk_entry_get_preferred_height (GtkWidget *widget, priv->ascent = pango_font_metrics_get_ascent (metrics); priv->descent = pango_font_metrics_get_descent (metrics); + pango_font_metrics_unref (metrics); _gtk_entry_get_borders (entry, &borders); + pango_layout_get_pixel_size (layout, NULL, &height); - height = PANGO_PIXELS (priv->ascent + priv->descent) + borders.top + borders.bottom; - - pango_font_metrics_unref (metrics); + height += borders.top + borders.bottom; *minimum = height; *natural = height; diff --git a/gtk/gtkspinbutton.c b/gtk/gtkspinbutton.c index b5523dbfe4..915f8ba6f3 100644 --- a/gtk/gtkspinbutton.c +++ b/gtk/gtkspinbutton.c @@ -276,7 +276,7 @@ static void gtk_spin_button_real_change_value (GtkSpinButton *spin, static gint gtk_spin_button_default_input (GtkSpinButton *spin_button, gdouble *new_val); -static gint gtk_spin_button_default_output (GtkSpinButton *spin_button); +static void gtk_spin_button_default_output (GtkSpinButton *spin_button); static guint spinbutton_signals[LAST_SIGNAL] = {0}; @@ -1108,27 +1108,26 @@ gtk_spin_button_set_orientation (GtkSpinButton *spin, gtk_widget_queue_resize (GTK_WIDGET (spin)); } -static int -compute_double_length (double val, int digits) +static gint +measure_string_width (PangoLayout *layout, + const gchar *string) { - int a; - int extra; + gint width; - a = 1; - if (fabs (val) > 1.0) - a = floor (log10 (fabs (val))) + 1; + pango_layout_set_text (layout, string, -1); + pango_layout_get_pixel_size (layout, &width, NULL); - extra = 0; + return width; +} - /* The dot: */ - if (digits > 0) - extra++; +static gchar * +gtk_spin_button_format_for_value (GtkSpinButton *spin_button, + gdouble value) +{ + GtkSpinButtonPrivate *priv = spin_button->priv; + gchar *buf = g_strdup_printf ("%0.*f", priv->digits, value); - /* The sign: */ - if (val < 0) - extra++; - - return a + digits + extra; + return buf; } static void @@ -1147,52 +1146,42 @@ gtk_spin_button_get_preferred_width (GtkWidget *widget, if (gtk_entry_get_width_chars (entry) < 0) { - PangoContext *context; - const PangoFontDescription *font_desc; - PangoFontMetrics *metrics; - gint width; - gint w; - gint string_len; - gint max_string_len; - gint digit_width; + gint width, w; gboolean interior_focus; gint focus_width; GtkBorder borders; + PangoLayout *layout; + gchar *str; gtk_style_context_get_style (style_context, "interior-focus", &interior_focus, "focus-line-width", &focus_width, NULL); - font_desc = gtk_style_context_get_font (style_context, GTK_STATE_FLAG_NORMAL); - context = gtk_widget_get_pango_context (widget); - metrics = pango_context_get_metrics (context, font_desc, - pango_context_get_language (context)); - - digit_width = pango_font_metrics_get_approximate_digit_width (metrics); - digit_width = PANGO_SCALE * - ((digit_width + PANGO_SCALE - 1) / PANGO_SCALE); - - pango_font_metrics_unref (metrics); + layout = pango_layout_copy (gtk_entry_get_layout (entry)); /* Get max of MIN_SPIN_BUTTON_WIDTH, size of upper, size of lower */ width = MIN_SPIN_BUTTON_WIDTH; - max_string_len = MAX (10, compute_double_length (1e9 * gtk_adjustment_get_step_increment (priv->adjustment), - priv->digits)); - string_len = compute_double_length (gtk_adjustment_get_upper (priv->adjustment), - priv->digits); - w = PANGO_PIXELS (MIN (string_len, max_string_len) * digit_width); + str = gtk_spin_button_format_for_value (spin_button, + gtk_adjustment_get_upper (priv->adjustment)); + w = measure_string_width (layout, str); width = MAX (width, w); - string_len = compute_double_length (gtk_adjustment_get_lower (priv->adjustment), priv->digits); - w = PANGO_PIXELS (MIN (string_len, max_string_len) * digit_width); + g_free (str); + + str = gtk_spin_button_format_for_value (spin_button, + gtk_adjustment_get_lower (priv->adjustment)); + w = measure_string_width (layout, str); width = MAX (width, w); + g_free (str); _gtk_entry_get_borders (entry, &borders); width += borders.left + borders.right; *minimum = width; *natural = width; + + g_object_unref (layout); } if (priv->orientation == GTK_ORIENTATION_HORIZONTAL) @@ -1970,17 +1959,17 @@ gtk_spin_button_default_input (GtkSpinButton *spin_button, return FALSE; } -static gint +static void gtk_spin_button_default_output (GtkSpinButton *spin_button) { GtkSpinButtonPrivate *priv = spin_button->priv; - - gchar *buf = g_strdup_printf ("%0.*f", priv->digits, gtk_adjustment_get_value (priv->adjustment)); + gchar *buf = gtk_spin_button_format_for_value (spin_button, + gtk_adjustment_get_value (priv->adjustment)); if (strcmp (buf, gtk_entry_get_text (GTK_ENTRY (spin_button)))) gtk_entry_set_text (GTK_ENTRY (spin_button), buf); + g_free (buf); - return FALSE; }