Factor out _gtk_misc_get_padding_and_border

The new semi-private function will allow to implement support for css
padding and border in widgets inheriting from GtkMisc.
Use the new function for GtkLabel, GtkArrow and GtkImage.
This commit is contained in:
Paolo Borelli 2011-12-04 13:55:51 +01:00
parent bf7779bfb7
commit e34589ddea
5 changed files with 91 additions and 55 deletions

View File

@ -207,15 +207,15 @@ gtk_arrow_get_preferred_width (GtkWidget *widget,
gint *minimum_size,
gint *natural_size)
{
gint xpad;
GtkBorder border;
gtk_misc_get_padding (GTK_MISC (widget), &xpad, NULL);
_gtk_misc_get_padding_and_border (GTK_MISC (widget), &border);
if (minimum_size)
*minimum_size = MIN_ARROW_SIZE + xpad * 2;
*minimum_size = MIN_ARROW_SIZE + border.left + border.right;
if (natural_size)
*natural_size = MIN_ARROW_SIZE + xpad * 2;
*natural_size = MIN_ARROW_SIZE + border.left + border.right;
}
static void
@ -223,18 +223,17 @@ gtk_arrow_get_preferred_height (GtkWidget *widget,
gint *minimum_size,
gint *natural_size)
{
gint ypad;
GtkBorder border;
gtk_misc_get_padding (GTK_MISC (widget), NULL, &ypad);
_gtk_misc_get_padding_and_border (GTK_MISC (widget), &border);
if (minimum_size)
*minimum_size = MIN_ARROW_SIZE + ypad * 2;
*minimum_size = MIN_ARROW_SIZE + border.top + border.bottom;
if (natural_size)
*natural_size = MIN_ARROW_SIZE + ypad * 2;
*natural_size = MIN_ARROW_SIZE + border.top + border.bottom;
}
/**
* gtk_arrow_new:
* @arrow_type: a valid #GtkArrowType.
@ -306,19 +305,17 @@ gtk_arrow_set (GtkArrow *arrow,
}
}
static gboolean
gtk_arrow_draw (GtkWidget *widget,
cairo_t *cr)
{
GtkArrow *arrow = GTK_ARROW (widget);
GtkArrowPrivate *priv = arrow->priv;
GtkMisc *misc = GTK_MISC (widget);
GtkStyleContext *context;
gdouble x, y;
gint width, height;
gint extent;
gint xpad, ypad;
GtkBorder border;
gfloat xalign, yalign;
GtkArrowType effective_arrow_type;
gfloat arrow_scaling;
@ -330,11 +327,11 @@ gtk_arrow_draw (GtkWidget *widget,
context = gtk_widget_get_style_context (widget);
gtk_widget_style_get (widget, "arrow-scaling", &arrow_scaling, NULL);
gtk_misc_get_padding (misc, &xpad, &ypad);
gtk_misc_get_alignment (misc, &xalign, &yalign);
_gtk_misc_get_padding_and_border (GTK_MISC (widget), &border);
gtk_misc_get_alignment (GTK_MISC (widget), &xalign, &yalign);
width = gtk_widget_get_allocated_width (widget) - 2 * xpad;
height = gtk_widget_get_allocated_height (widget) - 2 * ypad;
width = gtk_widget_get_allocated_width (widget) - border.left - border.right;
height = gtk_widget_get_allocated_height (widget) - border.top - border.bottom;
extent = MIN (width, height) * arrow_scaling;
effective_arrow_type = priv->arrow_type;
@ -348,8 +345,8 @@ gtk_arrow_draw (GtkWidget *widget,
effective_arrow_type = GTK_ARROW_LEFT;
}
x = xpad + ((width - extent) * xalign);
y = ypad + ((height - extent) * yalign);
x = border.left + ((width - extent) * xalign);
y = border.top + ((height - extent) * yalign);
switch (effective_arrow_type)
{

View File

@ -1349,15 +1349,16 @@ gtk_image_get_preferred_size (GtkImage *image,
gint *height_out)
{
GtkImagePrivate *priv = image->priv;
gint xpad, ypad, width, height;
gint width, height;
GtkBorder border;
GtkStyleContext *context;
context = gtk_widget_get_style_context (GTK_WIDGET (image));
gtk_misc_get_padding (GTK_MISC (image), &xpad, &ypad);
_gtk_icon_helper_get_size (priv->icon_helper, context, &width, &height);
_gtk_misc_get_padding_and_border (GTK_MISC (image), &border);
width += 2 * xpad;
height += 2 * ypad;
width += border.left + border.right;
height += border.top + border.bottom;
if (width_out)
*width_out = width;
@ -1374,8 +1375,8 @@ gtk_image_draw (GtkWidget *widget,
GtkMisc *misc;
GtkStyleContext *context;
gint x, y, width, height;
gint xpad, ypad;
gfloat xalign, yalign;
GtkBorder border;
g_return_val_if_fail (GTK_IS_IMAGE (widget), FALSE);
@ -1386,14 +1387,19 @@ gtk_image_draw (GtkWidget *widget,
context = gtk_widget_get_style_context (widget);
gtk_misc_get_alignment (misc, &xalign, &yalign);
gtk_misc_get_padding (misc, &xpad, &ypad);
gtk_image_get_preferred_size (image, &width, &height);
_gtk_misc_get_padding_and_border (misc, &border);
if (gtk_widget_get_direction (widget) != GTK_TEXT_DIR_LTR)
xalign = 1.0 - xalign;
x = floor (xpad + ((gtk_widget_get_allocated_width (widget) - width) * xalign));
y = floor (ypad + ((gtk_widget_get_allocated_height (widget) - height) * yalign));
x = floor ((gtk_widget_get_allocated_width (widget) - width) * xalign);
y = floor ((gtk_widget_get_allocated_height (widget) - height) * yalign);
gtk_render_frame (context, cr, x, y, width, height);
x += border.left;
y += border.top;
if (gtk_image_get_storage_type (image) == GTK_IMAGE_ANIMATION)
{

View File

@ -3239,14 +3239,14 @@ gtk_label_update_layout_width (GtkLabel *label)
if (priv->ellipsize || priv->wrap)
{
GtkBorder border;
PangoRectangle logical;
gint xpad, ypad;
gint width, height;
gtk_misc_get_padding (GTK_MISC (label), &xpad, &ypad);
_gtk_misc_get_padding_and_border (GTK_MISC (label), &border);
width = gtk_widget_get_allocated_width (GTK_WIDGET (label)) - xpad * 2;
height = gtk_widget_get_allocated_height (GTK_WIDGET (label)) - ypad * 2;
width = gtk_widget_get_allocated_width (GTK_WIDGET (label)) - border.left - border.right;
height = gtk_widget_get_allocated_height (GTK_WIDGET (label)) - border.top - border.bottom;
if (priv->have_transform)
{
@ -3606,7 +3606,7 @@ gtk_label_get_preferred_size (GtkWidget *widget,
GtkLabelPrivate *priv = label->priv;
PangoRectangle required_rect;
PangoRectangle natural_rect;
gint xpad, ypad;
GtkBorder border;
gtk_label_get_preferred_layout_size (label, &required_rect, &natural_rect);
@ -3652,7 +3652,7 @@ gtk_label_get_preferred_size (GtkWidget *widget,
natural_rect.width = PANGO_PIXELS_CEIL (natural_rect.width);
natural_rect.height = PANGO_PIXELS_CEIL (natural_rect.height);
gtk_misc_get_padding (GTK_MISC (label), &xpad, &ypad);
_gtk_misc_get_padding_and_border (GTK_MISC (label), &border);
if (orientation == GTK_ORIENTATION_HORIZONTAL)
{
@ -3678,8 +3678,8 @@ gtk_label_get_preferred_size (GtkWidget *widget,
*natural_size = natural_rect.width;
}
*minimum_size += xpad * 2;
*natural_size += xpad * 2;
*minimum_size += border.left + border.right;
*natural_size += border.left + border.right;
}
else /* GTK_ORIENTATION_VERTICAL */
{
@ -3706,12 +3706,11 @@ gtk_label_get_preferred_size (GtkWidget *widget,
*natural_size = natural_rect.height;
}
*minimum_size += ypad * 2;
*natural_size += ypad * 2;
*minimum_size += border.top + border.bottom;
*natural_size += border.top + border.bottom;
}
}
static void
gtk_label_get_preferred_width (GtkWidget *widget,
gint *minimum_size,
@ -3739,22 +3738,22 @@ gtk_label_get_preferred_width_for_height (GtkWidget *widget,
if (priv->wrap && (priv->angle == 90 || priv->angle == 270))
{
gint xpad, ypad;
GtkBorder border;
gtk_misc_get_padding (GTK_MISC (label), &xpad, &ypad);
_gtk_misc_get_padding_and_border (GTK_MISC (label), &border);
if (priv->wrap)
gtk_label_clear_layout (label);
get_size_for_allocation (label, GTK_ORIENTATION_VERTICAL,
MAX (1, height - (ypad * 2)),
MAX (1, height - border.top - border.bottom),
minimum_width, natural_width);
if (minimum_width)
*minimum_width += xpad * 2;
*minimum_width += border.right + border.left;
if (natural_width)
*natural_width += xpad * 2;
*natural_width += border.right + border.left;
}
else
GTK_WIDGET_GET_CLASS (widget)->get_preferred_width (widget, minimum_width, natural_width);
@ -3771,22 +3770,22 @@ gtk_label_get_preferred_height_for_width (GtkWidget *widget,
if (priv->wrap && (priv->angle == 0 || priv->angle == 180 || priv->angle == 360))
{
gint xpad, ypad;
GtkBorder border;
gtk_misc_get_padding (GTK_MISC (label), &xpad, &ypad);
_gtk_misc_get_padding_and_border (GTK_MISC (label), &border);
if (priv->wrap)
gtk_label_clear_layout (label);
get_size_for_allocation (label, GTK_ORIENTATION_HORIZONTAL,
MAX (1, width - xpad * 2),
MAX (1, width - border.left - border.right),
minimum_height, natural_height);
if (minimum_height)
*minimum_height += ypad * 2;
*minimum_height += border.top + border.bottom;
if (natural_height)
*natural_height += ypad * 2;
*natural_height += border.top + border.bottom;
}
else
GTK_WIDGET_GET_CLASS (widget)->get_preferred_height (widget, minimum_height, natural_height);
@ -3906,9 +3905,9 @@ get_layout_location (GtkLabel *label,
GtkMisc *misc;
GtkWidget *widget;
GtkLabelPrivate *priv;
GtkBorder border;
gint req_width, x, y;
gint req_height;
gint xpad, ypad;
gfloat xalign, yalign;
PangoRectangle logical;
@ -3917,7 +3916,7 @@ get_layout_location (GtkLabel *label,
priv = label->priv;
gtk_misc_get_alignment (misc, &xalign, &yalign);
gtk_misc_get_padding (misc, &xpad, &ypad);
_gtk_misc_get_padding_and_border (GTK_MISC (label), &border);
if (gtk_widget_get_direction (widget) != GTK_TEXT_DIR_LTR)
xalign = 1.0 - xalign;
@ -3936,13 +3935,12 @@ get_layout_location (GtkLabel *label,
req_width = logical.width;
req_height = logical.height;
req_width += 2 * xpad;
req_height += 2 * ypad;
req_width += border.left + border.right;
req_height += border.top + border.bottom;
gtk_widget_get_allocation (widget, &allocation);
x = floor (allocation.x + xpad + xalign * (allocation.width - req_width) - logical.x);
x = floor (allocation.x + border.left + xalign * (allocation.width - req_width) - logical.x);
/* bgo#315462 - For single-line labels, *do* align the requisition with
* respect to the allocation, even if we are under-allocated. For multi-line
@ -3958,9 +3956,9 @@ get_layout_location (GtkLabel *label,
* middle". You want to read the first line, at least, to get some context.
*/
if (pango_layout_get_line_count (priv->layout) == 1)
y = floor (allocation.y + ypad + (allocation.height - req_height) * yalign) - logical.y;
y = floor (allocation.y + border.top + (allocation.height - req_height) * yalign) - logical.y;
else
y = floor (allocation.y + ypad + MAX ((allocation.height - req_height) * yalign, 0)) - logical.y;
y = floor (allocation.y + border.top + MAX ((allocation.height - req_height) * yalign, 0)) - logical.y;
if (xp)
*xp = x;

View File

@ -403,3 +403,36 @@ gtk_misc_realize (GtkWidget *widget)
gdk_window_set_background_pattern (window, NULL);
}
}
/* Semi-private function used by gtk widgets inheriting from
* GtkMisc that takes into account both css padding and border
* and the padding specified with the GtkMisc properties.
*/
void
_gtk_misc_get_padding_and_border (GtkMisc *misc,
GtkBorder *border)
{
GtkStyleContext *context;
GtkStateFlags state;
GtkBorder tmp;
gint xpad, ypad;
g_return_if_fail (GTK_IS_MISC (misc));
context = gtk_widget_get_style_context (GTK_WIDGET (misc));
state = gtk_widget_get_state_flags (GTK_WIDGET (misc));
gtk_style_context_get_padding (context, state, border);
gtk_misc_get_padding (misc, &xpad, &ypad);
border->right = border->left = xpad;
border->top = border->bottom = xpad;
gtk_style_context_get_border (context, state, &tmp);
border->top += tmp.top;
border->right += tmp.right;
border->bottom += tmp.bottom;
border->left += tmp.left;
}

View File

@ -83,6 +83,8 @@ void gtk_misc_get_padding (GtkMisc *misc,
gint *xpad,
gint *ypad);
void _gtk_misc_get_padding_and_border (GtkMisc *misc,
GtkBorder *border);
G_END_DECLS