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
This commit is contained in:
Cosimo Cecchi 2012-09-02 19:14:04 -04:00
parent afd99d3579
commit d05191a010
2 changed files with 40 additions and 49 deletions

View File

@ -3273,7 +3273,9 @@ gtk_entry_get_preferred_height (GtkWidget *widget,
GtkStateFlags state; GtkStateFlags state;
PangoContext *context; PangoContext *context;
gint height; gint height;
PangoLayout *layout;
layout = gtk_entry_ensure_layout (entry, TRUE);
context = gtk_widget_get_pango_context (widget); context = gtk_widget_get_pango_context (widget);
style_context = gtk_widget_get_style_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->ascent = pango_font_metrics_get_ascent (metrics);
priv->descent = pango_font_metrics_get_descent (metrics); priv->descent = pango_font_metrics_get_descent (metrics);
pango_font_metrics_unref (metrics);
_gtk_entry_get_borders (entry, &borders); _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; height += borders.top + borders.bottom;
pango_font_metrics_unref (metrics);
*minimum = height; *minimum = height;
*natural = height; *natural = height;

View File

@ -276,7 +276,7 @@ static void gtk_spin_button_real_change_value (GtkSpinButton *spin,
static gint gtk_spin_button_default_input (GtkSpinButton *spin_button, static gint gtk_spin_button_default_input (GtkSpinButton *spin_button,
gdouble *new_val); 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}; 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)); gtk_widget_queue_resize (GTK_WIDGET (spin));
} }
static int static gint
compute_double_length (double val, int digits) measure_string_width (PangoLayout *layout,
const gchar *string)
{ {
int a; gint width;
int extra;
a = 1; pango_layout_set_text (layout, string, -1);
if (fabs (val) > 1.0) pango_layout_get_pixel_size (layout, &width, NULL);
a = floor (log10 (fabs (val))) + 1;
extra = 0; return width;
}
/* The dot: */ static gchar *
if (digits > 0) gtk_spin_button_format_for_value (GtkSpinButton *spin_button,
extra++; gdouble value)
{
GtkSpinButtonPrivate *priv = spin_button->priv;
gchar *buf = g_strdup_printf ("%0.*f", priv->digits, value);
/* The sign: */ return buf;
if (val < 0)
extra++;
return a + digits + extra;
} }
static void static void
@ -1147,52 +1146,42 @@ gtk_spin_button_get_preferred_width (GtkWidget *widget,
if (gtk_entry_get_width_chars (entry) < 0) if (gtk_entry_get_width_chars (entry) < 0)
{ {
PangoContext *context; gint width, w;
const PangoFontDescription *font_desc;
PangoFontMetrics *metrics;
gint width;
gint w;
gint string_len;
gint max_string_len;
gint digit_width;
gboolean interior_focus; gboolean interior_focus;
gint focus_width; gint focus_width;
GtkBorder borders; GtkBorder borders;
PangoLayout *layout;
gchar *str;
gtk_style_context_get_style (style_context, gtk_style_context_get_style (style_context,
"interior-focus", &interior_focus, "interior-focus", &interior_focus,
"focus-line-width", &focus_width, "focus-line-width", &focus_width,
NULL); NULL);
font_desc = gtk_style_context_get_font (style_context, GTK_STATE_FLAG_NORMAL);
context = gtk_widget_get_pango_context (widget); layout = pango_layout_copy (gtk_entry_get_layout (entry));
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);
/* Get max of MIN_SPIN_BUTTON_WIDTH, size of upper, size of lower */ /* Get max of MIN_SPIN_BUTTON_WIDTH, size of upper, size of lower */
width = MIN_SPIN_BUTTON_WIDTH; 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), str = gtk_spin_button_format_for_value (spin_button,
priv->digits); gtk_adjustment_get_upper (priv->adjustment));
w = PANGO_PIXELS (MIN (string_len, max_string_len) * digit_width); w = measure_string_width (layout, str);
width = MAX (width, w); width = MAX (width, w);
string_len = compute_double_length (gtk_adjustment_get_lower (priv->adjustment), priv->digits); g_free (str);
w = PANGO_PIXELS (MIN (string_len, max_string_len) * digit_width);
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); width = MAX (width, w);
g_free (str);
_gtk_entry_get_borders (entry, &borders); _gtk_entry_get_borders (entry, &borders);
width += borders.left + borders.right; width += borders.left + borders.right;
*minimum = width; *minimum = width;
*natural = width; *natural = width;
g_object_unref (layout);
} }
if (priv->orientation == GTK_ORIENTATION_HORIZONTAL) if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
@ -1970,17 +1959,17 @@ gtk_spin_button_default_input (GtkSpinButton *spin_button,
return FALSE; return FALSE;
} }
static gint static void
gtk_spin_button_default_output (GtkSpinButton *spin_button) gtk_spin_button_default_output (GtkSpinButton *spin_button)
{ {
GtkSpinButtonPrivate *priv = spin_button->priv; GtkSpinButtonPrivate *priv = spin_button->priv;
gchar *buf = gtk_spin_button_format_for_value (spin_button,
gchar *buf = g_strdup_printf ("%0.*f", priv->digits, gtk_adjustment_get_value (priv->adjustment)); gtk_adjustment_get_value (priv->adjustment));
if (strcmp (buf, gtk_entry_get_text (GTK_ENTRY (spin_button)))) if (strcmp (buf, gtk_entry_get_text (GTK_ENTRY (spin_button))))
gtk_entry_set_text (GTK_ENTRY (spin_button), buf); gtk_entry_set_text (GTK_ENTRY (spin_button), buf);
g_free (buf); g_free (buf);
return FALSE;
} }