Compare commits
12 Commits
matthiasc/
...
widget-pad
Author | SHA1 | Date | |
---|---|---|---|
|
68fa31e268 | ||
|
f0d841beed | ||
|
59b45073fe | ||
|
248267badb | ||
|
35a666c534 | ||
|
a171c499c3 | ||
|
d2243056e5 | ||
|
6c780fa93b | ||
|
3cd07cb78c | ||
|
a0a0495145 | ||
|
ed06fbd674 | ||
|
4b409c3c28 |
11
gtk/gtkbin.c
11
gtk/gtkbin.c
@@ -214,10 +214,15 @@ get_child_padding_delta (GtkBin *bin,
|
||||
gint *delta_v)
|
||||
{
|
||||
GtkBinPrivate *priv = bin->priv;
|
||||
gint hmin, vmin, child_hmin, child_vmin;
|
||||
gint hmin, vmin, hnat, vnat, child_hmin, child_vmin;
|
||||
|
||||
gtk_size_request_get_width (GTK_SIZE_REQUEST (bin), &hmin, NULL);
|
||||
gtk_size_request_get_height (GTK_SIZE_REQUEST (bin), &vmin, NULL);
|
||||
/* we can't use gtk_size_request_get_width() wrapper because we want
|
||||
* our "original" request, not any external adjustments from
|
||||
* set_size_request() or whatever. we have to ask for natural also
|
||||
* because NULL isn't allowed for the direct vfuncs
|
||||
*/
|
||||
GTK_SIZE_REQUEST_GET_IFACE (bin)->get_width(GTK_SIZE_REQUEST (bin), &hmin, &hnat);
|
||||
GTK_SIZE_REQUEST_GET_IFACE (bin)->get_height (GTK_SIZE_REQUEST (bin), &vmin, &vnat);
|
||||
|
||||
gtk_size_request_get_width (GTK_SIZE_REQUEST (priv->child), &child_hmin, NULL);
|
||||
gtk_size_request_get_height (GTK_SIZE_REQUEST (priv->child), &child_vmin, NULL);
|
||||
|
@@ -227,6 +227,7 @@ gtk_button_class_init (GtkButtonClass *klass)
|
||||
|
||||
container_class->child_type = gtk_button_child_type;
|
||||
container_class->add = gtk_button_add;
|
||||
gtk_container_class_handle_border_width (container_class);
|
||||
|
||||
klass->pressed = gtk_real_button_pressed;
|
||||
klass->released = gtk_real_button_released;
|
||||
@@ -1284,19 +1285,16 @@ gtk_button_realize (GtkWidget *widget)
|
||||
GdkWindow *window;
|
||||
GdkWindowAttr attributes;
|
||||
gint attributes_mask;
|
||||
gint border_width;
|
||||
|
||||
gtk_widget_get_allocation (widget, &allocation);
|
||||
|
||||
gtk_widget_set_realized (widget, TRUE);
|
||||
|
||||
border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
|
||||
|
||||
attributes.window_type = GDK_WINDOW_CHILD;
|
||||
attributes.x = allocation.x + border_width;
|
||||
attributes.y = allocation.y + border_width;
|
||||
attributes.width = allocation.width - border_width * 2;
|
||||
attributes.height = allocation.height - border_width * 2;
|
||||
attributes.x = allocation.x;
|
||||
attributes.y = allocation.y;
|
||||
attributes.width = allocation.width;
|
||||
attributes.height = allocation.height;
|
||||
attributes.wclass = GDK_INPUT_ONLY;
|
||||
attributes.event_mask = gtk_widget_get_events (widget);
|
||||
attributes.event_mask |= (GDK_BUTTON_PRESS_MASK |
|
||||
@@ -1455,7 +1453,6 @@ gtk_button_size_allocate (GtkWidget *widget,
|
||||
GtkStyle *style;
|
||||
GtkWidget *child;
|
||||
|
||||
guint border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
|
||||
gint xthickness, ythickness;
|
||||
GtkBorder default_border;
|
||||
GtkBorder inner_border;
|
||||
@@ -1476,30 +1473,28 @@ gtk_button_size_allocate (GtkWidget *widget,
|
||||
|
||||
if (gtk_widget_get_realized (widget))
|
||||
gdk_window_move_resize (button->event_window,
|
||||
allocation->x + border_width,
|
||||
allocation->y + border_width,
|
||||
allocation->width - border_width * 2,
|
||||
allocation->height - border_width * 2);
|
||||
allocation->x,
|
||||
allocation->y,
|
||||
allocation->width,
|
||||
allocation->height);
|
||||
|
||||
child = gtk_bin_get_child (GTK_BIN (button));
|
||||
if (child && gtk_widget_get_visible (child))
|
||||
{
|
||||
child_allocation.x = allocation->x + border_width + inner_border.left + xthickness;
|
||||
child_allocation.y = allocation->y + border_width + inner_border.top + ythickness;
|
||||
child_allocation.x = allocation->x + inner_border.left + xthickness;
|
||||
child_allocation.y = allocation->y + inner_border.top + ythickness;
|
||||
|
||||
child_allocation.width =
|
||||
allocation->width -
|
||||
xthickness * 2 -
|
||||
inner_border.left -
|
||||
inner_border.right -
|
||||
border_width * 2;
|
||||
inner_border.right;
|
||||
|
||||
child_allocation.height =
|
||||
allocation->height -
|
||||
ythickness * 2 -
|
||||
inner_border.top -
|
||||
inner_border.bottom -
|
||||
border_width * 2;
|
||||
inner_border.bottom;
|
||||
|
||||
if (gtk_widget_get_can_default (GTK_WIDGET (button)))
|
||||
{
|
||||
@@ -1548,7 +1543,6 @@ _gtk_button_paint (GtkButton *button,
|
||||
GtkWidget *widget;
|
||||
gint width, height;
|
||||
gint x, y;
|
||||
gint border_width;
|
||||
GtkBorder default_border;
|
||||
GtkBorder default_outside_border;
|
||||
gboolean interior_focus;
|
||||
@@ -1563,8 +1557,6 @@ _gtk_button_paint (GtkButton *button,
|
||||
GdkWindow *window;
|
||||
GtkStyle *style;
|
||||
|
||||
border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
|
||||
|
||||
gtk_button_get_props (button, &default_border, &default_outside_border, NULL, &interior_focus);
|
||||
gtk_widget_style_get (widget,
|
||||
"focus-line-width", &focus_width,
|
||||
@@ -1575,10 +1567,10 @@ _gtk_button_paint (GtkButton *button,
|
||||
style = gtk_widget_get_style (widget);
|
||||
window = gtk_widget_get_window (widget);
|
||||
|
||||
x = allocation.x + border_width;
|
||||
y = allocation.y + border_width;
|
||||
width = allocation.width - border_width * 2;
|
||||
height = allocation.height - border_width * 2;
|
||||
x = allocation.x;
|
||||
y = allocation.y;
|
||||
width = allocation.width;
|
||||
height = allocation.height;
|
||||
|
||||
if (gtk_widget_has_default (widget) &&
|
||||
GTK_BUTTON (widget)->relief == GTK_RELIEF_NORMAL)
|
||||
@@ -1925,7 +1917,6 @@ gtk_button_get_size (GtkSizeRequest *widget,
|
||||
gint focus_width;
|
||||
gint focus_pad;
|
||||
gint minimum, natural;
|
||||
guint border_width;
|
||||
|
||||
gtk_button_get_props (button, &default_border, NULL, &inner_border, NULL);
|
||||
gtk_widget_style_get (GTK_WIDGET (widget),
|
||||
@@ -1933,12 +1924,11 @@ gtk_button_get_size (GtkSizeRequest *widget,
|
||||
"focus-padding", &focus_pad,
|
||||
NULL);
|
||||
|
||||
border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
|
||||
style = gtk_widget_get_style (GTK_WIDGET (widget));
|
||||
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
{
|
||||
minimum = ((border_width + style->xthickness) * 2 +
|
||||
minimum = (style->xthickness * 2 +
|
||||
inner_border.left + inner_border.right);
|
||||
|
||||
if (gtk_widget_get_can_default (GTK_WIDGET (widget)))
|
||||
@@ -1946,7 +1936,7 @@ gtk_button_get_size (GtkSizeRequest *widget,
|
||||
}
|
||||
else
|
||||
{
|
||||
minimum = ((border_width + style->ythickness) * 2 +
|
||||
minimum = (style->ythickness * 2 +
|
||||
inner_border.top + inner_border.bottom);
|
||||
|
||||
if (gtk_widget_get_can_default (GTK_WIDGET (widget)))
|
||||
|
@@ -6172,8 +6172,8 @@ gtk_combo_box_get_height (GtkSizeRequest *widget,
|
||||
|
||||
/* Combo box is height-for-width only
|
||||
* (so we always just reserve enough height for the minimum width) */
|
||||
gtk_size_request_get_width (widget, &min_width, NULL);
|
||||
gtk_size_request_get_height_for_width (widget, min_width, minimum_size, natural_size);
|
||||
GTK_SIZE_REQUEST_GET_IFACE (widget)->get_width (widget, &min_width, NULL);
|
||||
GTK_SIZE_REQUEST_GET_IFACE (widget)->get_height_for_width (widget, min_width, minimum_size, natural_size);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -6184,7 +6184,7 @@ gtk_combo_box_get_width_for_height (GtkSizeRequest *widget,
|
||||
{
|
||||
/* Combo box is height-for-width only
|
||||
* (so we assume we always reserved enough height for the minimum width) */
|
||||
gtk_size_request_get_width (widget, minimum_size, natural_size);
|
||||
GTK_SIZE_REQUEST_GET_IFACE (widget)->get_width (widget, minimum_size, natural_size);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -107,6 +107,13 @@ static gint gtk_container_expose (GtkWidget *widget,
|
||||
GdkEventExpose *event);
|
||||
static void gtk_container_map (GtkWidget *widget);
|
||||
static void gtk_container_unmap (GtkWidget *widget);
|
||||
static void gtk_container_adjust_size_request (GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
gint for_size,
|
||||
gint *minimum_size,
|
||||
gint *natural_size);
|
||||
static void gtk_container_adjust_size_allocation (GtkWidget *widget,
|
||||
GtkAllocation *allocation);
|
||||
|
||||
static gchar* gtk_container_child_default_composite_name (GtkContainer *container,
|
||||
GtkWidget *child);
|
||||
@@ -233,7 +240,10 @@ gtk_container_class_init (GtkContainerClass *class)
|
||||
widget_class->map = gtk_container_map;
|
||||
widget_class->unmap = gtk_container_unmap;
|
||||
widget_class->focus = gtk_container_focus;
|
||||
|
||||
|
||||
widget_class->adjust_size_request = gtk_container_adjust_size_request;
|
||||
widget_class->adjust_size_allocation = gtk_container_adjust_size_allocation;
|
||||
|
||||
class->add = gtk_container_add_unimplemented;
|
||||
class->remove = gtk_container_remove_unimplemented;
|
||||
class->check_resize = gtk_container_real_check_resize;
|
||||
@@ -1520,6 +1530,103 @@ gtk_container_resize_children (GtkContainer *container)
|
||||
gtk_widget_set_allocation (widget, &allocation);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_container_adjust_size_request (GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
gint for_size,
|
||||
gint *minimum_size,
|
||||
gint *natural_size)
|
||||
{
|
||||
GtkContainer *container;
|
||||
|
||||
container = GTK_CONTAINER (widget);
|
||||
|
||||
if (GTK_CONTAINER_GET_CLASS (widget)->handle_border_width)
|
||||
{
|
||||
int border_width;
|
||||
|
||||
border_width = container->priv->border_width;
|
||||
|
||||
*minimum_size += border_width * 2;
|
||||
*natural_size += border_width * 2;
|
||||
}
|
||||
|
||||
/* chain up last so gtk_widget_set_size_request() values
|
||||
* will have a chance to overwrite our border width.
|
||||
*/
|
||||
parent_class->adjust_size_request (widget, orientation, for_size,
|
||||
minimum_size, natural_size);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_container_adjust_size_allocation (GtkWidget *widget,
|
||||
GtkAllocation *allocation)
|
||||
{
|
||||
GtkContainer *container;
|
||||
int border_width;
|
||||
|
||||
container = GTK_CONTAINER (widget);
|
||||
|
||||
parent_class->adjust_size_allocation (widget, allocation);
|
||||
|
||||
if (!GTK_CONTAINER_GET_CLASS (widget)->handle_border_width)
|
||||
return;
|
||||
|
||||
border_width = container->priv->border_width;
|
||||
|
||||
allocation->width -= border_width * 2;
|
||||
allocation->height -= border_width * 2;
|
||||
|
||||
/* If we get a pathological too-small allocation to hold
|
||||
* even the border width, leave all allocation to the actual
|
||||
* widget, and leave x,y unchanged. (GtkWidget's min size is
|
||||
* 1x1 if you're wondering why <1 and not <0)
|
||||
*
|
||||
* As long as we have space, set x,y properly.
|
||||
*/
|
||||
|
||||
if (allocation->width < 1)
|
||||
{
|
||||
allocation->width += border_width * 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
allocation->x += border_width;
|
||||
}
|
||||
|
||||
if (allocation->height < 1)
|
||||
{
|
||||
allocation->height += border_width * 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
allocation->y += border_width;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_container_class_handle_border_width:
|
||||
* @klass: the class struct of a #GtkContainer subclass
|
||||
*
|
||||
* Modifies a subclass of #GtkContainerClass to automatically add and
|
||||
* remove the border-width setting on GtkContainer. This allows the
|
||||
* subclass to ignore the border width in its size request and
|
||||
* allocate methods. The intent is for a subclass to invoke this
|
||||
* in its class_init function.
|
||||
*
|
||||
* gtk_container_class_handle_border_width() is necessary because it
|
||||
* would break API too badly to make this behavior the default. So
|
||||
* subclasses must "opt in" to the parent class handling border_width
|
||||
* for them.
|
||||
*/
|
||||
void
|
||||
gtk_container_class_handle_border_width (GtkContainerClass *klass)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_CONTAINER_CLASS (klass));
|
||||
|
||||
klass->handle_border_width = TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_container_forall:
|
||||
* @container: a #GtkContainer
|
||||
|
@@ -62,6 +62,8 @@ struct _GtkContainerClass
|
||||
{
|
||||
GtkWidgetClass parent_class;
|
||||
|
||||
unsigned int handle_border_width : 1;
|
||||
|
||||
void (*add) (GtkContainer *container,
|
||||
GtkWidget *widget);
|
||||
void (*remove) (GtkContainer *container,
|
||||
@@ -194,6 +196,8 @@ void gtk_container_forall (GtkContainer *container,
|
||||
GtkCallback callback,
|
||||
gpointer callback_data);
|
||||
|
||||
void gtk_container_class_handle_border_width (GtkContainerClass *klass);
|
||||
|
||||
/* Non-public methods */
|
||||
void _gtk_container_queue_resize (GtkContainer *container);
|
||||
void _gtk_container_clear_resize_widgets (GtkContainer *container);
|
||||
|
@@ -35,6 +35,36 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/**
|
||||
* GtkAlign:
|
||||
*
|
||||
* @GTK_ALIGN_FILL: stretch to fill all space if possible, center if
|
||||
* no meaningful way to stretch
|
||||
* @GTK_ALIGN_START: snap to left or top side, leaving space on right
|
||||
* or bottom
|
||||
* @GTK_ALIGN_END: snap to right or bottom side, leaving space on left
|
||||
* or top
|
||||
* @GTK_ALIGN_CENTER: center natural width of widget inside the
|
||||
* allocation
|
||||
*
|
||||
* Controls how a widget deals with extra space in a single (x or y)
|
||||
* dimension.
|
||||
*
|
||||
* Alignment only matters if the widget receives a "too large"
|
||||
* allocation, for example if you packed the widget with the "expand"
|
||||
* flag inside a #GtkBox, then the widget might get extra space. If
|
||||
* you have for example a 16x16 icon inside a 32x32 space, the icon
|
||||
* could be scaled and stretched, it could be centered, or it could be
|
||||
* positioned to one side of the space.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
GTK_ALIGN_FILL,
|
||||
GTK_ALIGN_START,
|
||||
GTK_ALIGN_END,
|
||||
GTK_ALIGN_CENTER
|
||||
} GtkAlign;
|
||||
|
||||
/* Arrow placement */
|
||||
typedef enum
|
||||
{
|
||||
|
@@ -1495,8 +1495,7 @@ gtk_expander_get_width_for_height (GtkSizeRequest *widget,
|
||||
gint *minimum_width,
|
||||
gint *natural_width)
|
||||
{
|
||||
gtk_size_request_get_width (widget, minimum_width, natural_width);
|
||||
//GTK_SIZE_REQUEST_GET_IFACE (widget)->get_width (widget, minimum_width, natural_width);
|
||||
GTK_SIZE_REQUEST_GET_IFACE (widget)->get_width (widget, minimum_width, natural_width);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -925,7 +925,7 @@ gtk_frame_get_width_for_height (GtkSizeRequest *widget,
|
||||
gint *minimum_width,
|
||||
gint *natural_width)
|
||||
{
|
||||
gtk_size_request_get_width (widget, minimum_width, natural_width);
|
||||
GTK_SIZE_REQUEST_GET_IFACE (widget)->get_width (widget, minimum_width, natural_width);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -3150,8 +3150,8 @@ gtk_menu_get_height (GtkSizeRequest *widget,
|
||||
gint min_width;
|
||||
|
||||
/* Menus are height-for-width only, just return the height for the minimum width */
|
||||
gtk_size_request_get_width (widget, &min_width, NULL);
|
||||
gtk_size_request_get_height_for_width (widget, min_width, minimum_size, natural_size);
|
||||
GTK_SIZE_REQUEST_GET_IFACE (widget)->get_width (widget, &min_width, NULL);
|
||||
GTK_SIZE_REQUEST_GET_IFACE (widget)->get_height_for_width (widget, min_width, minimum_size, natural_size);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -1941,6 +1941,7 @@ gtk_rc_property_parse_border (const GParamSpec *pspec,
|
||||
GtkBorder border;
|
||||
GScanner *scanner;
|
||||
gboolean success = FALSE;
|
||||
int left, right, top, bottom;
|
||||
|
||||
g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), FALSE);
|
||||
g_return_val_if_fail (G_VALUE_HOLDS_BOXED (property_value), FALSE);
|
||||
@@ -1948,11 +1949,15 @@ gtk_rc_property_parse_border (const GParamSpec *pspec,
|
||||
scanner = gtk_rc_scanner_new ();
|
||||
g_scanner_input_text (scanner, gstring->str, gstring->len);
|
||||
|
||||
if (get_braced_int (scanner, TRUE, FALSE, &border.left) &&
|
||||
get_braced_int (scanner, FALSE, FALSE, &border.right) &&
|
||||
get_braced_int (scanner, FALSE, FALSE, &border.top) &&
|
||||
get_braced_int (scanner, FALSE, TRUE, &border.bottom))
|
||||
if (get_braced_int (scanner, TRUE, FALSE, &left) &&
|
||||
get_braced_int (scanner, FALSE, FALSE, &right) &&
|
||||
get_braced_int (scanner, FALSE, FALSE, &top) &&
|
||||
get_braced_int (scanner, FALSE, TRUE, &bottom))
|
||||
{
|
||||
border.left = left;
|
||||
border.right = right;
|
||||
border.top = top;
|
||||
border.bottom = bottom;
|
||||
g_value_set_boxed (property_value, &border);
|
||||
success = TRUE;
|
||||
}
|
||||
|
@@ -666,35 +666,23 @@ static gint
|
||||
get_base_dimension (GtkWidget *widget,
|
||||
GtkSizeGroupMode mode)
|
||||
{
|
||||
GtkWidgetAuxInfo *aux_info = _gtk_widget_get_aux_info (widget, FALSE);
|
||||
|
||||
if (mode == GTK_SIZE_GROUP_HORIZONTAL)
|
||||
{
|
||||
if (aux_info && aux_info->width > 0)
|
||||
return aux_info->width;
|
||||
else
|
||||
{
|
||||
/* XXX Possibly we should be using natural values and not minimums here. */
|
||||
gint width;
|
||||
/* XXX Possibly we should be using natural values and not minimums here. */
|
||||
gint width;
|
||||
|
||||
gtk_size_request_get_width (GTK_SIZE_REQUEST (widget), &width, NULL);
|
||||
gtk_size_request_get_width (GTK_SIZE_REQUEST (widget), &width, NULL);
|
||||
|
||||
return width;
|
||||
}
|
||||
return width;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (aux_info && aux_info->height > 0)
|
||||
return aux_info->height;
|
||||
else
|
||||
{
|
||||
/* XXX Possibly we should be using natural values and not minimums here. */
|
||||
gint height;
|
||||
/* XXX Possibly we should be using natural values and not minimums here. */
|
||||
gint height;
|
||||
|
||||
gtk_size_request_get_height (GTK_SIZE_REQUEST (widget), &height, NULL);
|
||||
gtk_size_request_get_height (GTK_SIZE_REQUEST (widget), &height, NULL);
|
||||
|
||||
return height;
|
||||
}
|
||||
return height;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -801,31 +789,14 @@ _gtk_size_group_bump_requisition (GtkWidget *widget,
|
||||
|
||||
if (!is_bumping (widget))
|
||||
{
|
||||
GtkWidgetAuxInfo *aux_info =
|
||||
_gtk_widget_get_aux_info (widget, FALSE);
|
||||
|
||||
/* Avoid recursion here */
|
||||
mark_bumping (widget, TRUE);
|
||||
|
||||
if (get_size_groups (widget))
|
||||
{
|
||||
if (aux_info)
|
||||
{
|
||||
if (mode == GTK_SIZE_GROUP_HORIZONTAL)
|
||||
result = compute_dimension (widget, mode, MAX (aux_info->width, widget_requisition));
|
||||
else
|
||||
result = compute_dimension (widget, mode, MAX (aux_info->height, widget_requisition));
|
||||
}
|
||||
else
|
||||
result = compute_dimension (widget, mode, widget_requisition);
|
||||
}
|
||||
else if (aux_info)
|
||||
{
|
||||
if (mode == GTK_SIZE_GROUP_HORIZONTAL)
|
||||
result = MAX (aux_info->width, widget_requisition);
|
||||
else
|
||||
result = MAX (aux_info->height, widget_requisition);
|
||||
result = compute_dimension (widget, mode, widget_requisition);
|
||||
}
|
||||
|
||||
mark_bumping (widget, FALSE);
|
||||
}
|
||||
return result;
|
||||
|
@@ -155,6 +155,57 @@ do_size_request (GtkWidget *widget,
|
||||
g_signal_emit_by_name (widget, "size-request", requisition);
|
||||
}
|
||||
|
||||
#ifndef G_DISABLE_CHECKS
|
||||
static GQuark recursion_check_quark = 0;
|
||||
#endif /* G_DISABLE_CHECKS */
|
||||
|
||||
static void
|
||||
push_recursion_check (GtkSizeRequest *request,
|
||||
GtkSizeGroupMode orientation,
|
||||
gint for_size)
|
||||
{
|
||||
#ifndef G_DISABLE_CHECKS
|
||||
const char *previous_method;
|
||||
const char *method;
|
||||
|
||||
if (recursion_check_quark == 0)
|
||||
recursion_check_quark = g_quark_from_static_string ("gtk-size-request-in-progress");
|
||||
|
||||
previous_method = g_object_get_qdata (G_OBJECT (request), recursion_check_quark);
|
||||
|
||||
if (orientation == GTK_SIZE_GROUP_HORIZONTAL)
|
||||
{
|
||||
method = for_size < 0 ? "get_width" : "get_width_for_height";
|
||||
}
|
||||
else
|
||||
{
|
||||
method = for_size < 0 ? "get_height" : "get_height_for_width";
|
||||
}
|
||||
|
||||
if (previous_method != NULL)
|
||||
{
|
||||
g_warning ("%s %p: widget tried to gtk_size_request_%s inside "
|
||||
" GtkSizeRequest::%s implementation. "
|
||||
"Should just invoke GTK_SIZE_REQUEST_GET_IFACE(widget)->%s "
|
||||
"directly rather than using gtk_size_request_%s",
|
||||
G_OBJECT_TYPE_NAME (request), request,
|
||||
method, previous_method,
|
||||
method, method);
|
||||
}
|
||||
|
||||
g_object_set_qdata (G_OBJECT (request), recursion_check_quark, (char*) method);
|
||||
#endif /* G_DISABLE_CHECKS */
|
||||
}
|
||||
|
||||
static void
|
||||
pop_recursion_check (GtkSizeRequest *request,
|
||||
GtkSizeGroupMode orientation)
|
||||
{
|
||||
#ifndef G_DISABLE_CHECKS
|
||||
g_object_set_qdata (G_OBJECT (request), recursion_check_quark, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
compute_size_for_orientation (GtkSizeRequest *request,
|
||||
GtkSizeGroupMode orientation,
|
||||
@@ -166,6 +217,7 @@ compute_size_for_orientation (GtkSizeRequest *request,
|
||||
SizeRequest *cached_size;
|
||||
GtkWidget *widget;
|
||||
gboolean found_in_cache = FALSE;
|
||||
int adjusted_min, adjusted_natural;
|
||||
|
||||
g_return_if_fail (GTK_IS_SIZE_REQUEST (request));
|
||||
g_return_if_fail (minimum_size != NULL || natural_size != NULL);
|
||||
@@ -207,6 +259,7 @@ compute_size_for_orientation (GtkSizeRequest *request,
|
||||
/* Unconditional size request runs but is often unhandled. */
|
||||
do_size_request (widget, &requisition);
|
||||
|
||||
push_recursion_check (request, orientation, for_size);
|
||||
if (orientation == GTK_SIZE_GROUP_HORIZONTAL)
|
||||
{
|
||||
requisition_size = requisition.width;
|
||||
@@ -227,6 +280,7 @@ compute_size_for_orientation (GtkSizeRequest *request,
|
||||
GTK_SIZE_REQUEST_GET_IFACE (request)->get_height_for_width (request, for_size,
|
||||
&min_size, &nat_size);
|
||||
}
|
||||
pop_recursion_check (request, orientation);
|
||||
|
||||
if (min_size > nat_size)
|
||||
{
|
||||
@@ -259,12 +313,45 @@ compute_size_for_orientation (GtkSizeRequest *request,
|
||||
GTK_PRIVATE_UNSET_FLAG (request, GTK_HEIGHT_REQUEST_NEEDED);
|
||||
}
|
||||
|
||||
adjusted_min = cached_size->minimum_size;
|
||||
adjusted_natural = cached_size->natural_size;
|
||||
GTK_WIDGET_GET_CLASS (request)->adjust_size_request (GTK_WIDGET (request),
|
||||
orientation == GTK_SIZE_GROUP_HORIZONTAL ?
|
||||
GTK_ORIENTATION_HORIZONTAL :
|
||||
GTK_ORIENTATION_VERTICAL,
|
||||
cached_size->for_size,
|
||||
&adjusted_min,
|
||||
&adjusted_natural);
|
||||
|
||||
if (adjusted_min < cached_size->minimum_size ||
|
||||
adjusted_natural < cached_size->natural_size)
|
||||
{
|
||||
g_warning ("%s %p adjusted size %s min %d natural %d must not decrease below min %d natural %d",
|
||||
G_OBJECT_TYPE_NAME (request), request,
|
||||
orientation == GTK_SIZE_GROUP_VERTICAL ? "vertical" : "horizontal",
|
||||
adjusted_min, adjusted_natural,
|
||||
cached_size->minimum_size, cached_size->natural_size);
|
||||
/* don't use the adjustment */
|
||||
}
|
||||
else if (adjusted_min > adjusted_natural)
|
||||
{
|
||||
g_warning ("%s %p adjusted size %s min %d natural %d original min %d natural %d has min greater than natural",
|
||||
G_OBJECT_TYPE_NAME (request), request,
|
||||
orientation == GTK_SIZE_GROUP_VERTICAL ? "vertical" : "horizontal",
|
||||
adjusted_min, adjusted_natural,
|
||||
cached_size->minimum_size, cached_size->natural_size);
|
||||
/* don't use the adjustment */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* adjustment looks good */
|
||||
cached_size->minimum_size = adjusted_min;
|
||||
cached_size->natural_size = adjusted_natural;
|
||||
}
|
||||
|
||||
/* Get size groups to compute the base requisition once one
|
||||
* of the values have been cached, then go ahead and update
|
||||
* the cache with the sizegroup computed value.
|
||||
*
|
||||
* Note this is also where values from gtk_widget_set_size_request()
|
||||
* are considered.
|
||||
*/
|
||||
group_size =
|
||||
_gtk_size_group_bump_requisition (GTK_WIDGET (request),
|
||||
|
@@ -416,10 +416,10 @@ struct _GtkStyleClass
|
||||
*/
|
||||
struct _GtkBorder
|
||||
{
|
||||
gint left;
|
||||
gint right;
|
||||
gint top;
|
||||
gint bottom;
|
||||
gint16 left;
|
||||
gint16 right;
|
||||
gint16 top;
|
||||
gint16 bottom;
|
||||
};
|
||||
|
||||
GType gtk_style_get_type (void) G_GNUC_CONST;
|
||||
|
609
gtk/gtkwidget.c
609
gtk/gtkwidget.c
@@ -278,7 +278,14 @@ enum {
|
||||
PROP_TOOLTIP_MARKUP,
|
||||
PROP_TOOLTIP_TEXT,
|
||||
PROP_WINDOW,
|
||||
PROP_DOUBLE_BUFFERED
|
||||
PROP_DOUBLE_BUFFERED,
|
||||
PROP_H_ALIGN,
|
||||
PROP_V_ALIGN,
|
||||
PROP_MARGIN_LEFT,
|
||||
PROP_MARGIN_RIGHT,
|
||||
PROP_MARGIN_TOP,
|
||||
PROP_MARGIN_BOTTOM,
|
||||
PROP_MARGIN
|
||||
};
|
||||
|
||||
typedef struct _GtkStateData GtkStateData;
|
||||
@@ -315,7 +322,7 @@ static void gtk_widget_real_unrealize (GtkWidget *widget);
|
||||
static void gtk_widget_real_size_request (GtkWidget *widget,
|
||||
GtkRequisition *requisition);
|
||||
static void gtk_widget_real_size_allocate (GtkWidget *widget,
|
||||
GtkAllocation *allocation);
|
||||
GtkAllocation *allocation);
|
||||
static void gtk_widget_real_style_set (GtkWidget *widget,
|
||||
GtkStyle *previous_style);
|
||||
static void gtk_widget_real_direction_changed(GtkWidget *widget,
|
||||
@@ -359,6 +366,7 @@ static gint gtk_widget_event_internal (GtkWidget *widget,
|
||||
GdkEvent *event);
|
||||
static gboolean gtk_widget_real_mnemonic_activate (GtkWidget *widget,
|
||||
gboolean group_cycling);
|
||||
static const GtkWidgetAuxInfo* _gtk_widget_get_aux_info_or_defaults (GtkWidget *widget);
|
||||
static void gtk_widget_aux_info_destroy (GtkWidgetAuxInfo *aux_info);
|
||||
static AtkObject* gtk_widget_real_get_accessible (GtkWidget *widget);
|
||||
static void gtk_widget_accessible_interface_init (AtkImplementorIface *iface);
|
||||
@@ -407,7 +415,16 @@ static void gtk_widget_real_get_height (GtkSizeRequest
|
||||
gint *natural_size);
|
||||
|
||||
static void gtk_widget_queue_tooltip_query (GtkWidget *widget);
|
||||
|
||||
|
||||
|
||||
static void gtk_widget_real_adjust_size_request (GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
gint for_size,
|
||||
gint *minimum_size,
|
||||
gint *natural_size);
|
||||
static void gtk_widget_real_adjust_size_allocation (GtkWidget *widget,
|
||||
GtkAllocation *allocation);
|
||||
|
||||
static void gtk_widget_set_usize_internal (GtkWidget *widget,
|
||||
gint width,
|
||||
gint height);
|
||||
@@ -621,6 +638,9 @@ gtk_widget_class_init (GtkWidgetClass *klass)
|
||||
|
||||
klass->no_expose_event = NULL;
|
||||
|
||||
klass->adjust_size_request = gtk_widget_real_adjust_size_request;
|
||||
klass->adjust_size_allocation = gtk_widget_real_adjust_size_allocation;
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_NAME,
|
||||
g_param_spec_string ("name",
|
||||
@@ -850,6 +870,140 @@ gtk_widget_class_init (GtkWidgetClass *klass)
|
||||
TRUE,
|
||||
GTK_PARAM_READWRITE));
|
||||
|
||||
/**
|
||||
* GtkWidget:h-align
|
||||
*
|
||||
* How to distribute horizontal space if widget gets extra space, see #GtkAlign
|
||||
*
|
||||
* Since: 3.0
|
||||
*/
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_H_ALIGN,
|
||||
g_param_spec_enum ("h-align",
|
||||
P_("Horizontal Alignment"),
|
||||
P_("How to position in extra horizontal space"),
|
||||
GTK_TYPE_ALIGN,
|
||||
GTK_ALIGN_FILL,
|
||||
GTK_PARAM_READWRITE));
|
||||
|
||||
/**
|
||||
* GtkWidget:v-align
|
||||
*
|
||||
* How to distribute vertical space if widget gets extra space, see #GtkAlign
|
||||
*
|
||||
* Since: 3.0
|
||||
*/
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_V_ALIGN,
|
||||
g_param_spec_enum ("v-align",
|
||||
P_("Vertical Alignment"),
|
||||
P_("How to position in extra vertical space"),
|
||||
GTK_TYPE_ALIGN,
|
||||
GTK_ALIGN_FILL,
|
||||
GTK_PARAM_READWRITE));
|
||||
|
||||
/**
|
||||
* GtkWidget:margin-left
|
||||
*
|
||||
* Margin on left side of widget.
|
||||
*
|
||||
* This property adds margin outside of the widget's normal size
|
||||
* request, the margin will be added in addition to the size from
|
||||
* gtk_widget_set_size_request() for example.
|
||||
*
|
||||
* Since: 3.0
|
||||
*/
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_MARGIN_LEFT,
|
||||
g_param_spec_int ("margin-left",
|
||||
P_("Margin on Left"),
|
||||
P_("Pixels of extra space on the left side"),
|
||||
0,
|
||||
G_MAXINT16,
|
||||
0,
|
||||
GTK_PARAM_READWRITE));
|
||||
|
||||
/**
|
||||
* GtkWidget:margin-right
|
||||
*
|
||||
* Margin on right side of widget.
|
||||
*
|
||||
* This property adds margin outside of the widget's normal size
|
||||
* request, the margin will be added in addition to the size from
|
||||
* gtk_widget_set_size_request() for example.
|
||||
*
|
||||
* Since: 3.0
|
||||
*/
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_MARGIN_RIGHT,
|
||||
g_param_spec_int ("margin-right",
|
||||
P_("Margin on Right"),
|
||||
P_("Pixels of extra space on the right side"),
|
||||
0,
|
||||
G_MAXINT16,
|
||||
0,
|
||||
GTK_PARAM_READWRITE));
|
||||
|
||||
/**
|
||||
* GtkWidget:margin-top
|
||||
*
|
||||
* Margin on top side of widget.
|
||||
*
|
||||
* This property adds margin outside of the widget's normal size
|
||||
* request, the margin will be added in addition to the size from
|
||||
* gtk_widget_set_size_request() for example.
|
||||
*
|
||||
* Since: 3.0
|
||||
*/
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_MARGIN_TOP,
|
||||
g_param_spec_int ("margin-top",
|
||||
P_("Margin on Top"),
|
||||
P_("Pixels of extra space on the top side"),
|
||||
0,
|
||||
G_MAXINT16,
|
||||
0,
|
||||
GTK_PARAM_READWRITE));
|
||||
|
||||
/**
|
||||
* GtkWidget:margin-bottom
|
||||
*
|
||||
* Margin on bottom side of widget.
|
||||
*
|
||||
* This property adds margin outside of the widget's normal size
|
||||
* request, the margin will be added in addition to the size from
|
||||
* gtk_widget_set_size_request() for example.
|
||||
*
|
||||
* Since: 3.0
|
||||
*/
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_MARGIN_BOTTOM,
|
||||
g_param_spec_int ("margin-bottom",
|
||||
P_("Margin on Bottom"),
|
||||
P_("Pixels of extra space on the bottom side"),
|
||||
0,
|
||||
G_MAXINT16,
|
||||
0,
|
||||
GTK_PARAM_READWRITE));
|
||||
|
||||
/**
|
||||
* GtkWidget:margin
|
||||
*
|
||||
* Sets all four sides' margin at once. If read, returns max
|
||||
* margin on any side.
|
||||
*
|
||||
* Since: 3.0
|
||||
*/
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_MARGIN,
|
||||
g_param_spec_int ("margin",
|
||||
P_("All Margins"),
|
||||
P_("Pixels of extra space on all four sides"),
|
||||
0,
|
||||
G_MAXINT16,
|
||||
0,
|
||||
GTK_PARAM_READWRITE));
|
||||
|
||||
/**
|
||||
* GtkWidget::show:
|
||||
* @widget: the object which received the signal.
|
||||
@@ -2787,6 +2941,32 @@ gtk_widget_set_property (GObject *object,
|
||||
case PROP_DOUBLE_BUFFERED:
|
||||
gtk_widget_set_double_buffered (widget, g_value_get_boolean (value));
|
||||
break;
|
||||
case PROP_H_ALIGN:
|
||||
gtk_widget_set_h_align (widget, g_value_get_enum (value));
|
||||
break;
|
||||
case PROP_V_ALIGN:
|
||||
gtk_widget_set_v_align (widget, g_value_get_enum (value));
|
||||
break;
|
||||
case PROP_MARGIN_LEFT:
|
||||
gtk_widget_set_margin_left (widget, g_value_get_int (value));
|
||||
break;
|
||||
case PROP_MARGIN_RIGHT:
|
||||
gtk_widget_set_margin_right (widget, g_value_get_int (value));
|
||||
break;
|
||||
case PROP_MARGIN_TOP:
|
||||
gtk_widget_set_margin_top (widget, g_value_get_int (value));
|
||||
break;
|
||||
case PROP_MARGIN_BOTTOM:
|
||||
gtk_widget_set_margin_bottom (widget, g_value_get_int (value));
|
||||
break;
|
||||
case PROP_MARGIN:
|
||||
g_object_freeze_notify (G_OBJECT (widget));
|
||||
gtk_widget_set_margin_left (widget, g_value_get_int (value));
|
||||
gtk_widget_set_margin_right (widget, g_value_get_int (value));
|
||||
gtk_widget_set_margin_top (widget, g_value_get_int (value));
|
||||
gtk_widget_set_margin_bottom (widget, g_value_get_int (value));
|
||||
g_object_thaw_notify (G_OBJECT (widget));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@@ -2897,6 +3077,40 @@ gtk_widget_get_property (GObject *object,
|
||||
case PROP_DOUBLE_BUFFERED:
|
||||
g_value_set_boolean (value, gtk_widget_get_double_buffered (widget));
|
||||
break;
|
||||
case PROP_H_ALIGN:
|
||||
g_value_set_enum (value, gtk_widget_get_h_align (widget));
|
||||
break;
|
||||
case PROP_V_ALIGN:
|
||||
g_value_set_enum (value, gtk_widget_get_v_align (widget));
|
||||
break;
|
||||
case PROP_MARGIN_LEFT:
|
||||
g_value_set_int (value, gtk_widget_get_margin_left (widget));
|
||||
break;
|
||||
case PROP_MARGIN_RIGHT:
|
||||
g_value_set_int (value, gtk_widget_get_margin_right (widget));
|
||||
break;
|
||||
case PROP_MARGIN_TOP:
|
||||
g_value_set_int (value, gtk_widget_get_margin_top (widget));
|
||||
break;
|
||||
case PROP_MARGIN_BOTTOM:
|
||||
g_value_set_int (value, gtk_widget_get_margin_bottom (widget));
|
||||
break;
|
||||
case PROP_MARGIN:
|
||||
{
|
||||
GtkWidgetAuxInfo *aux_info = _gtk_widget_get_aux_info (widget, FALSE);
|
||||
if (aux_info == NULL)
|
||||
{
|
||||
g_value_set_int (value, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_value_set_int (value, MAX (MAX (aux_info->margin.left,
|
||||
aux_info->margin.right),
|
||||
MAX (aux_info->margin.top,
|
||||
aux_info->margin.bottom)));
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@@ -3968,7 +4182,11 @@ gtk_widget_queue_shallow_draw (GtkWidget *widget)
|
||||
* @allocation: (inout): position and size to be allocated to @widget
|
||||
*
|
||||
* This function is only used by #GtkContainer subclasses, to assign a size
|
||||
* and position to their child widgets.
|
||||
* and position to their child widgets.
|
||||
*
|
||||
* In this function, the allocation may be adjusted. It will be forced
|
||||
* to a 1x1 minimum size, and the adjust_size_allocation virtual method
|
||||
* on the child will be used to adjust the allocation.
|
||||
**/
|
||||
void
|
||||
gtk_widget_size_allocate (GtkWidget *widget,
|
||||
@@ -3977,6 +4195,7 @@ gtk_widget_size_allocate (GtkWidget *widget,
|
||||
GtkWidgetPrivate *priv;
|
||||
GdkRectangle real_allocation;
|
||||
GdkRectangle old_allocation;
|
||||
GdkRectangle adjusted_allocation;
|
||||
gboolean alloc_needed;
|
||||
gboolean size_changed;
|
||||
gboolean position_changed;
|
||||
@@ -4015,6 +4234,27 @@ gtk_widget_size_allocate (GtkWidget *widget,
|
||||
old_allocation = priv->allocation;
|
||||
real_allocation = *allocation;
|
||||
|
||||
adjusted_allocation = real_allocation;
|
||||
GTK_WIDGET_GET_CLASS (widget)->adjust_size_allocation (widget, &adjusted_allocation);
|
||||
|
||||
if (adjusted_allocation.x < real_allocation.x ||
|
||||
adjusted_allocation.y < real_allocation.y ||
|
||||
(adjusted_allocation.x + adjusted_allocation.width) >
|
||||
(real_allocation.x + real_allocation.width) ||
|
||||
(adjusted_allocation.y + adjusted_allocation.height >
|
||||
real_allocation.y + real_allocation.height))
|
||||
{
|
||||
g_warning ("%s %p attempted to adjust its size allocation from %d,%d %dx%d to %d,%d %dx%d. adjust_size_allocation must keep allocation inside original bounds",
|
||||
G_OBJECT_TYPE_NAME (widget), widget,
|
||||
real_allocation.x, real_allocation.y, real_allocation.width, real_allocation.height,
|
||||
adjusted_allocation.x, adjusted_allocation.y, adjusted_allocation.width, adjusted_allocation.height);
|
||||
adjusted_allocation = real_allocation; /* veto it */
|
||||
}
|
||||
else
|
||||
{
|
||||
real_allocation = adjusted_allocation;
|
||||
}
|
||||
|
||||
if (real_allocation.width < 0 || real_allocation.height < 0)
|
||||
{
|
||||
g_warning ("gtk_widget_size_allocate(): attempt to allocate widget with width %d and height %d",
|
||||
@@ -4269,6 +4509,122 @@ gtk_widget_real_size_allocate (GtkWidget *widget,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
get_span_inside_border (GtkWidget *widget,
|
||||
GtkAlign align,
|
||||
int start_pad,
|
||||
int end_pad,
|
||||
int allocated_outside_size,
|
||||
int natural_inside_size,
|
||||
int *coord_inside_p,
|
||||
int *size_inside_p)
|
||||
{
|
||||
int inside_allocated;
|
||||
int content_size;
|
||||
int coord, size;
|
||||
|
||||
inside_allocated = allocated_outside_size - start_pad - end_pad;
|
||||
|
||||
content_size = natural_inside_size;
|
||||
if (content_size > inside_allocated)
|
||||
{
|
||||
/* didn't get full natural size */
|
||||
content_size = inside_allocated;
|
||||
}
|
||||
|
||||
coord = size = 0; /* silence compiler */
|
||||
switch (align)
|
||||
{
|
||||
case GTK_ALIGN_FILL:
|
||||
coord = start_pad;
|
||||
size = inside_allocated;
|
||||
break;
|
||||
case GTK_ALIGN_START:
|
||||
coord = start_pad;
|
||||
size = content_size;
|
||||
break;
|
||||
case GTK_ALIGN_END:
|
||||
coord = allocated_outside_size - end_pad - content_size;
|
||||
size = content_size;
|
||||
break;
|
||||
case GTK_ALIGN_CENTER:
|
||||
coord = start_pad + (inside_allocated - content_size) / 2;
|
||||
size = content_size;
|
||||
break;
|
||||
}
|
||||
|
||||
if (coord_inside_p)
|
||||
*coord_inside_p = coord;
|
||||
|
||||
if (size_inside_p)
|
||||
*size_inside_p = size;
|
||||
}
|
||||
|
||||
static void
|
||||
get_span_inside_border_horizontal (GtkWidget *widget,
|
||||
const GtkWidgetAuxInfo *aux_info,
|
||||
int allocated_outside_width,
|
||||
int natural_inside_width,
|
||||
int *x_inside_p,
|
||||
int *width_inside_p)
|
||||
{
|
||||
get_span_inside_border (widget,
|
||||
aux_info->h_align,
|
||||
aux_info->margin.left,
|
||||
aux_info->margin.right,
|
||||
allocated_outside_width,
|
||||
natural_inside_width,
|
||||
x_inside_p,
|
||||
width_inside_p);
|
||||
}
|
||||
|
||||
static void
|
||||
get_span_inside_border_vertical (GtkWidget *widget,
|
||||
const GtkWidgetAuxInfo *aux_info,
|
||||
int allocated_outside_height,
|
||||
int natural_inside_height,
|
||||
int *y_inside_p,
|
||||
int *height_inside_p)
|
||||
{
|
||||
get_span_inside_border (widget,
|
||||
aux_info->v_align,
|
||||
aux_info->margin.top,
|
||||
aux_info->margin.bottom,
|
||||
allocated_outside_height,
|
||||
natural_inside_height,
|
||||
y_inside_p,
|
||||
height_inside_p);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_widget_real_adjust_size_allocation (GtkWidget *widget,
|
||||
GtkAllocation *allocation)
|
||||
{
|
||||
const GtkWidgetAuxInfo *aux_info;
|
||||
GtkRequisition min, natural;
|
||||
int x, y, w, h;
|
||||
|
||||
aux_info = _gtk_widget_get_aux_info_or_defaults (widget);
|
||||
|
||||
gtk_size_request_get_size (GTK_SIZE_REQUEST (widget), &min, &natural);
|
||||
|
||||
get_span_inside_border_horizontal (widget,
|
||||
aux_info,
|
||||
allocation->width,
|
||||
natural.width,
|
||||
&x, &w);
|
||||
get_span_inside_border_vertical (widget,
|
||||
aux_info,
|
||||
allocation->height,
|
||||
natural.height,
|
||||
&y, &h);
|
||||
|
||||
allocation->x += x;
|
||||
allocation->y += y;
|
||||
allocation->width = w;
|
||||
allocation->height = h;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_widget_real_can_activate_accel (GtkWidget *widget,
|
||||
guint signal_id)
|
||||
@@ -7979,6 +8335,11 @@ gtk_widget_set_usize_internal (GtkWidget *widget,
|
||||
*
|
||||
* Widgets can't actually be allocated a size less than 1 by 1, but
|
||||
* you can pass 0,0 to this function to mean "as small as possible."
|
||||
*
|
||||
* The size request set here does not include any margin from the
|
||||
* #GtkWidget properties margin-left, margin-right, margin-top, and
|
||||
* margin-bottom, but it does include pretty much all other padding
|
||||
* or border properties set by any subclass of #GtkWidget.
|
||||
**/
|
||||
void
|
||||
gtk_widget_set_size_request (GtkWidget *widget,
|
||||
@@ -8017,17 +8378,17 @@ gtk_widget_get_size_request (GtkWidget *widget,
|
||||
gint *width,
|
||||
gint *height)
|
||||
{
|
||||
GtkWidgetAuxInfo *aux_info;
|
||||
const GtkWidgetAuxInfo *aux_info;
|
||||
|
||||
g_return_if_fail (GTK_IS_WIDGET (widget));
|
||||
|
||||
aux_info = _gtk_widget_get_aux_info (widget, FALSE);
|
||||
aux_info = _gtk_widget_get_aux_info_or_defaults (widget);
|
||||
|
||||
if (width)
|
||||
*width = aux_info ? aux_info->width : -1;
|
||||
*width = aux_info->width;
|
||||
|
||||
if (height)
|
||||
*height = aux_info ? aux_info->height : -1;
|
||||
*height = aux_info->height;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -9053,6 +9414,46 @@ gtk_widget_real_size_request (GtkWidget *widget,
|
||||
requisition->height = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_widget_real_adjust_size_request (GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
gint for_size,
|
||||
gint *minimum_size,
|
||||
gint *natural_size)
|
||||
{
|
||||
const GtkWidgetAuxInfo *aux_info;
|
||||
|
||||
aux_info =_gtk_widget_get_aux_info_or_defaults (widget);
|
||||
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL &&
|
||||
aux_info->width > 0)
|
||||
{
|
||||
*minimum_size = MAX (*minimum_size, aux_info->width);
|
||||
}
|
||||
else if (orientation == GTK_ORIENTATION_VERTICAL &&
|
||||
aux_info->height > 0)
|
||||
{
|
||||
*minimum_size = MAX (*minimum_size, aux_info->height);
|
||||
}
|
||||
|
||||
/* Fix it if set_size_request made natural size smaller than min size.
|
||||
* This would also silently fix broken widgets, but we warn about them
|
||||
* in gtksizerequest.c when calling their size request vfuncs.
|
||||
*/
|
||||
*natural_size = MAX (*natural_size, *minimum_size);
|
||||
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
{
|
||||
*minimum_size += (aux_info->margin.left + aux_info->margin.right);
|
||||
*natural_size += (aux_info->margin.left + aux_info->margin.right);
|
||||
}
|
||||
else
|
||||
{
|
||||
*minimum_size += (aux_info->margin.top + aux_info->margin.bottom);
|
||||
*natural_size += (aux_info->margin.top + aux_info->margin.bottom);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* _gtk_widget_peek_colormap:
|
||||
*
|
||||
@@ -9555,6 +9956,13 @@ gtk_widget_propagate_state (GtkWidget *widget,
|
||||
}
|
||||
}
|
||||
|
||||
static const GtkWidgetAuxInfo default_aux_info = {
|
||||
-1, -1,
|
||||
GTK_ALIGN_FILL,
|
||||
GTK_ALIGN_FILL,
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
/*
|
||||
* _gtk_widget_get_aux_info:
|
||||
* @widget: a #GtkWidget
|
||||
@@ -9576,8 +9984,7 @@ _gtk_widget_get_aux_info (GtkWidget *widget,
|
||||
{
|
||||
aux_info = g_slice_new0 (GtkWidgetAuxInfo);
|
||||
|
||||
aux_info->width = -1;
|
||||
aux_info->height = -1;
|
||||
*aux_info = default_aux_info;
|
||||
|
||||
g_object_set_qdata (G_OBJECT (widget), quark_aux_info, aux_info);
|
||||
}
|
||||
@@ -9585,6 +9992,21 @@ _gtk_widget_get_aux_info (GtkWidget *widget,
|
||||
return aux_info;
|
||||
}
|
||||
|
||||
static const GtkWidgetAuxInfo*
|
||||
_gtk_widget_get_aux_info_or_defaults (GtkWidget *widget)
|
||||
{
|
||||
GtkWidgetAuxInfo *aux_info;
|
||||
|
||||
aux_info = _gtk_widget_get_aux_info (widget, FALSE);
|
||||
if (aux_info == NULL)
|
||||
{
|
||||
return &default_aux_info;
|
||||
}
|
||||
else
|
||||
{
|
||||
return aux_info;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************
|
||||
* gtk_widget_aux_info_destroy:
|
||||
@@ -11040,7 +11462,7 @@ gtk_widget_real_get_height_for_width (GtkSizeRequest *layout,
|
||||
gint *minimum_height,
|
||||
gint *natural_height)
|
||||
{
|
||||
gtk_size_request_get_height (layout, minimum_height, natural_height);
|
||||
GTK_SIZE_REQUEST_GET_IFACE (layout)->get_height(layout, minimum_height, natural_height);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -11048,8 +11470,8 @@ gtk_widget_real_get_width_for_height (GtkSizeRequest *layout,
|
||||
gint height,
|
||||
gint *minimum_width,
|
||||
gint *natural_width)
|
||||
{
|
||||
gtk_size_request_get_width (layout, minimum_width, natural_width);
|
||||
{
|
||||
GTK_SIZE_REQUEST_GET_IFACE (layout)->get_width(layout, minimum_width, natural_width);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -11060,8 +11482,165 @@ gtk_widget_size_request_init (GtkSizeRequestIface *iface)
|
||||
iface->get_width_for_height = gtk_widget_real_get_width_for_height;
|
||||
iface->get_height_for_width = gtk_widget_real_get_height_for_width;
|
||||
}
|
||||
|
||||
|
||||
|
||||
GtkAlign
|
||||
gtk_widget_get_h_align (GtkWidget *widget)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_WIDGET (widget), GTK_ALIGN_FILL);
|
||||
return _gtk_widget_get_aux_info_or_defaults (widget)->h_align;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_widget_set_h_align (GtkWidget *widget,
|
||||
GtkAlign align)
|
||||
{
|
||||
GtkWidgetAuxInfo *aux_info;
|
||||
|
||||
g_return_if_fail (GTK_IS_WIDGET (widget));
|
||||
|
||||
aux_info = _gtk_widget_get_aux_info (widget, TRUE);
|
||||
|
||||
if (aux_info->h_align == align)
|
||||
return;
|
||||
|
||||
aux_info->h_align = align;
|
||||
gtk_widget_queue_resize (widget);
|
||||
g_object_notify (G_OBJECT (widget), "h-align");
|
||||
}
|
||||
|
||||
GtkAlign
|
||||
gtk_widget_get_v_align (GtkWidget *widget)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_WIDGET (widget), GTK_ALIGN_FILL);
|
||||
return _gtk_widget_get_aux_info_or_defaults (widget)->v_align;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_widget_set_v_align (GtkWidget *widget,
|
||||
GtkAlign align)
|
||||
{
|
||||
GtkWidgetAuxInfo *aux_info;
|
||||
|
||||
g_return_if_fail (GTK_IS_WIDGET (widget));
|
||||
|
||||
aux_info = _gtk_widget_get_aux_info (widget, TRUE);
|
||||
|
||||
if (aux_info->v_align == align)
|
||||
return;
|
||||
|
||||
aux_info->v_align = align;
|
||||
gtk_widget_queue_resize (widget);
|
||||
g_object_notify (G_OBJECT (widget), "v-align");
|
||||
}
|
||||
|
||||
int
|
||||
gtk_widget_get_margin_left (GtkWidget *widget)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_WIDGET (widget), 0);
|
||||
|
||||
return _gtk_widget_get_aux_info_or_defaults (widget)->margin.left;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_widget_set_margin_left (GtkWidget *widget,
|
||||
int margin)
|
||||
{
|
||||
GtkWidgetAuxInfo *aux_info;
|
||||
|
||||
g_return_if_fail (GTK_IS_WIDGET (widget));
|
||||
g_return_if_fail (margin <= G_MAXINT16);
|
||||
|
||||
aux_info = _gtk_widget_get_aux_info (widget, TRUE);
|
||||
|
||||
if (aux_info->margin.left == margin)
|
||||
return;
|
||||
|
||||
aux_info->margin.left = margin;
|
||||
gtk_widget_queue_resize (widget);
|
||||
g_object_notify (G_OBJECT (widget), "margin-left");
|
||||
}
|
||||
|
||||
int
|
||||
gtk_widget_get_margin_right (GtkWidget *widget)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_WIDGET (widget), 0);
|
||||
|
||||
return _gtk_widget_get_aux_info_or_defaults (widget)->margin.right;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_widget_set_margin_right (GtkWidget *widget,
|
||||
int margin)
|
||||
{
|
||||
GtkWidgetAuxInfo *aux_info;
|
||||
|
||||
g_return_if_fail (GTK_IS_WIDGET (widget));
|
||||
g_return_if_fail (margin <= G_MAXINT16);
|
||||
|
||||
aux_info = _gtk_widget_get_aux_info (widget, TRUE);
|
||||
|
||||
if (aux_info->margin.right == margin)
|
||||
return;
|
||||
|
||||
aux_info->margin.right = margin;
|
||||
gtk_widget_queue_resize (widget);
|
||||
g_object_notify (G_OBJECT (widget), "margin-right");
|
||||
}
|
||||
|
||||
int
|
||||
gtk_widget_get_margin_top (GtkWidget *widget)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_WIDGET (widget), 0);
|
||||
|
||||
return _gtk_widget_get_aux_info_or_defaults (widget)->margin.top;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_widget_set_margin_top (GtkWidget *widget,
|
||||
int margin)
|
||||
{
|
||||
GtkWidgetAuxInfo *aux_info;
|
||||
|
||||
g_return_if_fail (GTK_IS_WIDGET (widget));
|
||||
g_return_if_fail (margin <= G_MAXINT16);
|
||||
|
||||
aux_info = _gtk_widget_get_aux_info (widget, TRUE);
|
||||
|
||||
if (aux_info->margin.top == margin)
|
||||
return;
|
||||
|
||||
aux_info->margin.top = margin;
|
||||
gtk_widget_queue_resize (widget);
|
||||
g_object_notify (G_OBJECT (widget), "margin-top");
|
||||
}
|
||||
|
||||
int
|
||||
gtk_widget_get_margin_bottom (GtkWidget *widget)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_WIDGET (widget), 0);
|
||||
|
||||
return _gtk_widget_get_aux_info_or_defaults (widget)->margin.bottom;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_widget_set_margin_bottom (GtkWidget *widget,
|
||||
int margin)
|
||||
{
|
||||
GtkWidgetAuxInfo *aux_info;
|
||||
|
||||
g_return_if_fail (GTK_IS_WIDGET (widget));
|
||||
g_return_if_fail (margin <= G_MAXINT16);
|
||||
|
||||
aux_info = _gtk_widget_get_aux_info (widget, TRUE);
|
||||
|
||||
if (aux_info->margin.bottom == margin)
|
||||
return;
|
||||
|
||||
aux_info->margin.bottom = margin;
|
||||
gtk_widget_queue_resize (widget);
|
||||
g_object_notify (G_OBJECT (widget), "margin-bottom");
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_widget_get_clipboard:
|
||||
* @widget: a #GtkWidget
|
||||
|
@@ -473,6 +473,15 @@ struct _GtkWidgetClass
|
||||
gint y,
|
||||
gboolean keyboard_tooltip,
|
||||
GtkTooltip *tooltip);
|
||||
|
||||
void (* adjust_size_request) (GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
gint for_size,
|
||||
gint *minimum_size,
|
||||
gint *natural_size);
|
||||
void (* adjust_size_allocation) (GtkWidget *widget,
|
||||
GtkAllocation *allocation);
|
||||
|
||||
/* Signals without a C default handler class slot:
|
||||
* gboolean (*damage_event) (GtkWidget *widget,
|
||||
* GdkEventExpose *event);
|
||||
@@ -493,6 +502,11 @@ struct _GtkWidgetAuxInfo
|
||||
{
|
||||
gint width;
|
||||
gint height;
|
||||
|
||||
guint h_align : 4;
|
||||
guint v_align : 4;
|
||||
|
||||
GtkBorder margin;
|
||||
};
|
||||
|
||||
struct _GtkWidgetShapeInfo
|
||||
@@ -721,6 +735,28 @@ void gtk_widget_set_support_multidevice (GtkWidget *widget,
|
||||
/* Accessibility support */
|
||||
AtkObject* gtk_widget_get_accessible (GtkWidget *widget);
|
||||
|
||||
|
||||
/* Margin and alignment */
|
||||
GtkAlign gtk_widget_get_h_align (GtkWidget *widget);
|
||||
void gtk_widget_set_h_align (GtkWidget *widget,
|
||||
GtkAlign align);
|
||||
GtkAlign gtk_widget_get_v_align (GtkWidget *widget);
|
||||
void gtk_widget_set_v_align (GtkWidget *widget,
|
||||
GtkAlign align);
|
||||
int gtk_widget_get_margin_left (GtkWidget *widget);
|
||||
void gtk_widget_set_margin_left (GtkWidget *widget,
|
||||
int margin);
|
||||
int gtk_widget_get_margin_right (GtkWidget *widget);
|
||||
void gtk_widget_set_margin_right (GtkWidget *widget,
|
||||
int margin);
|
||||
int gtk_widget_get_margin_top (GtkWidget *widget);
|
||||
void gtk_widget_set_margin_top (GtkWidget *widget,
|
||||
int margin);
|
||||
int gtk_widget_get_margin_bottom (GtkWidget *widget);
|
||||
void gtk_widget_set_margin_bottom (GtkWidget *widget,
|
||||
int margin);
|
||||
|
||||
|
||||
/* The following functions must not be called on an already
|
||||
* realized widget. Because it is possible that somebody
|
||||
* can call get_colormap() or get_visual() and save the
|
||||
|
@@ -1527,8 +1527,8 @@ gtk_wrap_box_get_width (GtkSizeRequest *widget,
|
||||
/* Return the width for the minimum height */
|
||||
gint min_height;
|
||||
|
||||
gtk_size_request_get_height (widget, &min_height, NULL);
|
||||
gtk_size_request_get_width_for_height (widget, min_height, &min_width, &nat_width);
|
||||
GTK_SIZE_REQUEST_GET_IFACE (widget)->get_height (widget, &min_height, NULL);
|
||||
GTK_SIZE_REQUEST_GET_IFACE (widget)->get_width_for_height (widget, min_height, &min_width, &nat_width);
|
||||
|
||||
}
|
||||
|
||||
@@ -1559,8 +1559,8 @@ gtk_wrap_box_get_height (GtkSizeRequest *widget,
|
||||
/* Return the height for the minimum width */
|
||||
gint min_width;
|
||||
|
||||
gtk_size_request_get_width (widget, &min_width, NULL);
|
||||
gtk_size_request_get_height_for_width (widget, min_width, &min_height, &nat_height);
|
||||
GTK_SIZE_REQUEST_GET_IFACE (widget)->get_width (widget, &min_width, NULL);
|
||||
GTK_SIZE_REQUEST_GET_IFACE (widget)->get_height_for_width (widget, min_width, &min_height, &nat_height);
|
||||
}
|
||||
else /* GTK_ORIENTATION_VERTICAL */
|
||||
{
|
||||
@@ -1637,7 +1637,7 @@ gtk_wrap_box_get_height_for_width (GtkSizeRequest *widget,
|
||||
gint min_width;
|
||||
|
||||
/* Make sure its no smaller than the minimum */
|
||||
gtk_size_request_get_width (widget, &min_width, NULL);
|
||||
GTK_SIZE_REQUEST_GET_IFACE (widget)->get_width (widget, &min_width, NULL);
|
||||
|
||||
border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
|
||||
|
||||
@@ -1771,7 +1771,7 @@ gtk_wrap_box_get_height_for_width (GtkSizeRequest *widget,
|
||||
else /* GTK_ORIENTATION_VERTICAL */
|
||||
{
|
||||
/* Return the minimum height */
|
||||
gtk_size_request_get_height (widget, &min_height, &nat_height);
|
||||
GTK_SIZE_REQUEST_GET_IFACE (widget)->get_height (widget, &min_height, &nat_height);
|
||||
}
|
||||
|
||||
if (minimum_height)
|
||||
@@ -1803,14 +1803,14 @@ gtk_wrap_box_get_width_for_height (GtkSizeRequest *widget,
|
||||
if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
{
|
||||
/* Return the minimum width */
|
||||
gtk_size_request_get_width (widget, &min_width, &nat_width);
|
||||
GTK_SIZE_REQUEST_GET_IFACE (widget)->get_width (widget, &min_width, &nat_width);
|
||||
}
|
||||
else /* GTK_ORIENTATION_VERTICAL */
|
||||
{
|
||||
gint min_height;
|
||||
|
||||
/* Make sure its no smaller than the minimum */
|
||||
gtk_size_request_get_height (widget, &min_height, NULL);
|
||||
GTK_SIZE_REQUEST_GET_IFACE (widget)->get_height (widget, &min_height, NULL);
|
||||
|
||||
border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
|
||||
|
||||
|
@@ -30,6 +30,7 @@ noinst_PROGRAMS = $(TEST_PROGS) \
|
||||
flicker \
|
||||
print-editor \
|
||||
testaccel \
|
||||
testadjustsize \
|
||||
testassistant \
|
||||
testbbox \
|
||||
testbuttons \
|
||||
@@ -117,6 +118,7 @@ testicontheme_DEPENDENCIES = $(TEST_DEPS)
|
||||
testiconview_DEPENDENCIES = $(TEST_DEPS)
|
||||
testaccel_DEPENDENCIES = $(TEST_DEPS)
|
||||
testapplication_DEPENDENCIES = $(TEST_DEPS)
|
||||
testadjustsize_DEPENDENCIES = $(TEST_DEPS)
|
||||
testassistant_DEPENDENCIES = $(TEST_DEPS)
|
||||
testbbox_DEPENDENCIES = $(TEST_DEPS)
|
||||
testbuttons_DEPENDENCIES = $(TEST_DEPS)
|
||||
@@ -179,6 +181,7 @@ flicker_LDADD = $(LDADDS)
|
||||
simple_LDADD = $(LDADDS)
|
||||
print_editor_LDADD = $(LDADDS)
|
||||
testaccel_LDADD = $(LDADDS)
|
||||
testadjustsize_LDADD = $(LDADDS)
|
||||
testapplication_LDADD = $(LDADDS)
|
||||
testassistant_LDADD = $(LDADDS)
|
||||
testbbox_LDADD = $(LDADDS)
|
||||
|
423
tests/testadjustsize.c
Normal file
423
tests/testadjustsize.c
Normal file
@@ -0,0 +1,423 @@
|
||||
/* testadjustsize.c
|
||||
* Copyright (C) 2010 Havoc Pennington
|
||||
*
|
||||
* Author:
|
||||
* Havoc Pennington <hp@pobox.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
static GtkWidget *test_window;
|
||||
|
||||
enum {
|
||||
TEST_WIDGET_LABEL,
|
||||
TEST_WIDGET_VERTICAL_LABEL,
|
||||
TEST_WIDGET_WRAP_LABEL,
|
||||
TEST_WIDGET_ALIGNMENT,
|
||||
TEST_WIDGET_IMAGE,
|
||||
TEST_WIDGET_BUTTON,
|
||||
TEST_WIDGET_LAST
|
||||
};
|
||||
|
||||
static GtkWidget *test_widgets[TEST_WIDGET_LAST];
|
||||
|
||||
static GtkWidget*
|
||||
create_image (void)
|
||||
{
|
||||
return gtk_image_new_from_stock (GTK_STOCK_OPEN,
|
||||
GTK_ICON_SIZE_BUTTON);
|
||||
}
|
||||
|
||||
static GtkWidget*
|
||||
create_label (gboolean vertical,
|
||||
gboolean wrap)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
|
||||
widget = gtk_label_new ("This is a label, label label label");
|
||||
|
||||
if (vertical)
|
||||
gtk_label_set_angle (GTK_LABEL (widget), 90);
|
||||
|
||||
if (wrap)
|
||||
gtk_label_set_line_wrap (GTK_LABEL (widget), TRUE);
|
||||
|
||||
return widget;
|
||||
}
|
||||
|
||||
static GtkWidget*
|
||||
create_button (void)
|
||||
{
|
||||
return gtk_button_new_with_label ("BUTTON!");
|
||||
}
|
||||
|
||||
static gboolean
|
||||
on_expose_alignment (GtkWidget *widget,
|
||||
GdkEventExpose *event,
|
||||
void *data)
|
||||
{
|
||||
cairo_t *cr;
|
||||
GtkAllocation allocation;
|
||||
|
||||
cr = gdk_cairo_create (event->window);
|
||||
|
||||
cairo_set_source_rgb (cr, 1.0, 0.0, 0.0);
|
||||
gtk_widget_get_allocation (widget, &allocation);
|
||||
cairo_rectangle (cr,
|
||||
allocation.x,
|
||||
allocation.y,
|
||||
allocation.width,
|
||||
allocation.height);
|
||||
cairo_fill (cr);
|
||||
|
||||
cairo_destroy (cr);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static GtkWidget*
|
||||
create_alignment (void)
|
||||
{
|
||||
GtkWidget *alignment;
|
||||
|
||||
alignment = gtk_alignment_new (0.5, 0.5, 1.0, 1.0);
|
||||
|
||||
/* make the alignment visible */
|
||||
gtk_widget_set_redraw_on_allocate (alignment, TRUE);
|
||||
g_signal_connect (G_OBJECT (alignment),
|
||||
"expose-event",
|
||||
G_CALLBACK (on_expose_alignment),
|
||||
NULL);
|
||||
|
||||
return alignment;
|
||||
}
|
||||
|
||||
static void
|
||||
open_test_window (void)
|
||||
{
|
||||
GtkWidget *table;
|
||||
int i;
|
||||
|
||||
test_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_title (GTK_WINDOW (test_window), "Tests");
|
||||
|
||||
g_signal_connect (test_window, "delete-event",
|
||||
G_CALLBACK (gtk_main_quit), test_window);
|
||||
|
||||
gtk_window_set_resizable (GTK_WINDOW (test_window), FALSE);
|
||||
|
||||
test_widgets[TEST_WIDGET_IMAGE] = create_image ();
|
||||
test_widgets[TEST_WIDGET_LABEL] = create_label (FALSE, FALSE);
|
||||
test_widgets[TEST_WIDGET_VERTICAL_LABEL] = create_label (TRUE, FALSE);
|
||||
test_widgets[TEST_WIDGET_WRAP_LABEL] = create_label (FALSE, TRUE);
|
||||
test_widgets[TEST_WIDGET_BUTTON] = create_button ();
|
||||
test_widgets[TEST_WIDGET_ALIGNMENT] = create_alignment ();
|
||||
|
||||
table = gtk_table_new (2, 3, FALSE);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (test_window), table);
|
||||
|
||||
for (i = 0; i < TEST_WIDGET_LAST; ++i)
|
||||
{
|
||||
gtk_table_attach (GTK_TABLE (table),
|
||||
test_widgets[i],
|
||||
i % 3,
|
||||
i % 3 + 1,
|
||||
i / 3,
|
||||
i / 3 + 1,
|
||||
0, 0, 0, 0);
|
||||
}
|
||||
|
||||
gtk_widget_show_all (test_window);
|
||||
}
|
||||
|
||||
static void
|
||||
on_toggle_border_widths (GtkToggleButton *button,
|
||||
void *data)
|
||||
{
|
||||
gboolean has_border;
|
||||
int i;
|
||||
|
||||
has_border = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button));
|
||||
|
||||
for (i = 0; i < TEST_WIDGET_LAST; ++i)
|
||||
{
|
||||
if (GTK_IS_CONTAINER (test_widgets[i]))
|
||||
{
|
||||
gtk_container_set_border_width (GTK_CONTAINER (test_widgets[i]),
|
||||
has_border ? 50 : 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
on_set_small_size_requests (GtkToggleButton *button,
|
||||
void *data)
|
||||
{
|
||||
gboolean has_small_size_requests;
|
||||
int i;
|
||||
|
||||
has_small_size_requests = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button));
|
||||
|
||||
for (i = 0; i < TEST_WIDGET_LAST; ++i)
|
||||
{
|
||||
gtk_widget_set_size_request (test_widgets[i],
|
||||
has_small_size_requests ? 5 : -1,
|
||||
has_small_size_requests ? 5 : -1);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
on_set_large_size_requests (GtkToggleButton *button,
|
||||
void *data)
|
||||
{
|
||||
gboolean has_large_size_requests;
|
||||
int i;
|
||||
|
||||
has_large_size_requests = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button));
|
||||
|
||||
for (i = 0; i < TEST_WIDGET_LAST; ++i)
|
||||
{
|
||||
gtk_widget_set_size_request (test_widgets[i],
|
||||
has_large_size_requests ? 200 : -1,
|
||||
has_large_size_requests ? 200 : -1);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
open_control_window (void)
|
||||
{
|
||||
GtkWidget *window;
|
||||
GtkWidget *box;
|
||||
GtkWidget *toggle;
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Controls");
|
||||
|
||||
g_signal_connect (window, "delete-event",
|
||||
G_CALLBACK (gtk_main_quit), window);
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, FALSE, 0);
|
||||
gtk_container_add (GTK_CONTAINER (window), box);
|
||||
|
||||
toggle =
|
||||
gtk_toggle_button_new_with_label ("Containers have borders");
|
||||
g_signal_connect (G_OBJECT (toggle),
|
||||
"toggled", G_CALLBACK (on_toggle_border_widths),
|
||||
NULL);
|
||||
gtk_container_add (GTK_CONTAINER (box), toggle);
|
||||
|
||||
toggle =
|
||||
gtk_toggle_button_new_with_label ("Set small size requests");
|
||||
g_signal_connect (G_OBJECT (toggle),
|
||||
"toggled", G_CALLBACK (on_set_small_size_requests),
|
||||
NULL);
|
||||
gtk_container_add (GTK_CONTAINER (box), toggle);
|
||||
|
||||
toggle =
|
||||
gtk_toggle_button_new_with_label ("Set large size requests");
|
||||
g_signal_connect (G_OBJECT (toggle),
|
||||
"toggled", G_CALLBACK (on_set_large_size_requests),
|
||||
NULL);
|
||||
gtk_container_add (GTK_CONTAINER (box), toggle);
|
||||
|
||||
|
||||
gtk_widget_show_all (window);
|
||||
}
|
||||
|
||||
#define TEST_WIDGET(outer) (gtk_bin_get_child (GTK_BIN (gtk_bin_get_child (GTK_BIN(outer)))))
|
||||
|
||||
static GtkWidget*
|
||||
create_widget_visible_border (const char *text)
|
||||
{
|
||||
GtkWidget *outer_box;
|
||||
GtkWidget *inner_box;
|
||||
GtkWidget *test_widget;
|
||||
GtkWidget *label;
|
||||
GdkColor color;
|
||||
|
||||
outer_box = gtk_event_box_new ();
|
||||
gdk_color_parse ("black", &color);
|
||||
gtk_widget_modify_bg (outer_box, GTK_STATE_NORMAL, &color);
|
||||
|
||||
inner_box = gtk_event_box_new ();
|
||||
gtk_container_set_border_width (GTK_CONTAINER (inner_box), 5);
|
||||
gdk_color_parse ("blue", &color);
|
||||
gtk_widget_modify_bg (inner_box, GTK_STATE_NORMAL, &color);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (outer_box), inner_box);
|
||||
|
||||
|
||||
test_widget = gtk_event_box_new ();
|
||||
gdk_color_parse ("red", &color);
|
||||
gtk_widget_modify_bg (test_widget, GTK_STATE_NORMAL, &color);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (inner_box), test_widget);
|
||||
|
||||
label = gtk_label_new (text);
|
||||
gtk_container_add (GTK_CONTAINER (test_widget), label);
|
||||
|
||||
g_assert (TEST_WIDGET (outer_box) == test_widget);
|
||||
|
||||
gtk_widget_show_all (outer_box);
|
||||
|
||||
return outer_box;
|
||||
}
|
||||
|
||||
static const char*
|
||||
enum_to_string (GType enum_type,
|
||||
int value)
|
||||
{
|
||||
GEnumValue *v;
|
||||
|
||||
v = g_enum_get_value (g_type_class_peek (enum_type), value);
|
||||
|
||||
return v->value_nick;
|
||||
}
|
||||
|
||||
static GtkWidget*
|
||||
create_aligned (GtkAlign h_align,
|
||||
GtkAlign v_align)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
char *label;
|
||||
|
||||
label = g_strdup_printf ("h=%s v=%s",
|
||||
enum_to_string (GTK_TYPE_ALIGN, h_align),
|
||||
enum_to_string (GTK_TYPE_ALIGN, v_align));
|
||||
|
||||
widget = create_widget_visible_border (label);
|
||||
|
||||
g_object_set (G_OBJECT (TEST_WIDGET (widget)),
|
||||
"h-align", h_align,
|
||||
"v-align", v_align,
|
||||
NULL);
|
||||
|
||||
return widget;
|
||||
}
|
||||
|
||||
static void
|
||||
open_alignment_window (void)
|
||||
{
|
||||
GtkWidget *table;
|
||||
int i;
|
||||
GEnumClass *align_class;
|
||||
|
||||
test_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_title (GTK_WINDOW (test_window), "Alignment");
|
||||
|
||||
g_signal_connect (test_window, "delete-event",
|
||||
G_CALLBACK (gtk_main_quit), test_window);
|
||||
|
||||
gtk_window_set_resizable (GTK_WINDOW (test_window), TRUE);
|
||||
gtk_window_set_default_size (GTK_WINDOW (test_window), 500, 500);
|
||||
|
||||
align_class = g_type_class_peek (GTK_TYPE_ALIGN);
|
||||
|
||||
table = gtk_table_new (align_class->n_values, align_class->n_values, TRUE);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (test_window), table);
|
||||
|
||||
for (i = 0; i < align_class->n_values; ++i)
|
||||
{
|
||||
int j;
|
||||
for (j = 0; j < align_class->n_values; ++j)
|
||||
{
|
||||
GtkWidget *child =
|
||||
create_aligned(align_class->values[i].value,
|
||||
align_class->values[j].value);
|
||||
|
||||
gtk_table_attach (GTK_TABLE (table),
|
||||
child,
|
||||
i, i + 1,
|
||||
j, j + 1,
|
||||
GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
gtk_widget_show_all (test_window);
|
||||
}
|
||||
|
||||
static GtkWidget*
|
||||
create_margined (const char *propname)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
|
||||
widget = create_widget_visible_border (propname);
|
||||
|
||||
g_object_set (G_OBJECT (TEST_WIDGET (widget)),
|
||||
propname, 15,
|
||||
NULL);
|
||||
|
||||
return widget;
|
||||
}
|
||||
|
||||
static void
|
||||
open_margin_window (void)
|
||||
{
|
||||
GtkWidget *table;
|
||||
int i;
|
||||
const char * margins[] = {
|
||||
"margin-left",
|
||||
"margin-right",
|
||||
"margin-top",
|
||||
"margin-bottom",
|
||||
"margin"
|
||||
};
|
||||
|
||||
test_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_title (GTK_WINDOW (test_window), "Margin");
|
||||
|
||||
g_signal_connect (test_window, "delete-event",
|
||||
G_CALLBACK (gtk_main_quit), test_window);
|
||||
|
||||
gtk_window_set_resizable (GTK_WINDOW (test_window), TRUE);
|
||||
|
||||
table = gtk_table_new (G_N_ELEMENTS (margins), 1, FALSE);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (test_window), table);
|
||||
|
||||
for (i = 0; i < (int) G_N_ELEMENTS (margins); ++i)
|
||||
{
|
||||
GtkWidget *child =
|
||||
create_margined(margins[i]);
|
||||
|
||||
gtk_table_attach (GTK_TABLE (table),
|
||||
child,
|
||||
0, 1,
|
||||
i, i + 1,
|
||||
GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
|
||||
}
|
||||
|
||||
gtk_widget_show_all (test_window);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
gtk_init (&argc, &argv);
|
||||
|
||||
open_test_window ();
|
||||
open_control_window ();
|
||||
open_alignment_window ();
|
||||
open_margin_window ();
|
||||
|
||||
gtk_main ();
|
||||
|
||||
return 0;
|
||||
}
|
Reference in New Issue
Block a user