GtkWidget: add adjust_size_request adjust_size_allocation virtual funcs
Use these new methods to handle set_size_request (aka aux_info) inside gtkwidget.c, instead of having external code mess with it. The virtual functions can be used for other purposes in the future. For example, GtkContainer::border_width could be automatically implemented for all container subclasses.
This commit is contained in:
@ -666,35 +666,23 @@ static gint
|
|||||||
get_base_dimension (GtkWidget *widget,
|
get_base_dimension (GtkWidget *widget,
|
||||||
GtkSizeGroupMode mode)
|
GtkSizeGroupMode mode)
|
||||||
{
|
{
|
||||||
GtkWidgetAuxInfo *aux_info = _gtk_widget_get_aux_info (widget, FALSE);
|
|
||||||
|
|
||||||
if (mode == GTK_SIZE_GROUP_HORIZONTAL)
|
if (mode == GTK_SIZE_GROUP_HORIZONTAL)
|
||||||
{
|
{
|
||||||
if (aux_info && aux_info->width > 0)
|
/* XXX Possibly we should be using natural values and not minimums here. */
|
||||||
return aux_info->width;
|
gint width;
|
||||||
else
|
|
||||||
{
|
|
||||||
/* 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
|
else
|
||||||
{
|
{
|
||||||
if (aux_info && aux_info->height > 0)
|
/* XXX Possibly we should be using natural values and not minimums here. */
|
||||||
return aux_info->height;
|
gint height;
|
||||||
else
|
|
||||||
{
|
|
||||||
/* 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))
|
if (!is_bumping (widget))
|
||||||
{
|
{
|
||||||
GtkWidgetAuxInfo *aux_info =
|
|
||||||
_gtk_widget_get_aux_info (widget, FALSE);
|
|
||||||
|
|
||||||
/* Avoid recursion here */
|
/* Avoid recursion here */
|
||||||
mark_bumping (widget, TRUE);
|
mark_bumping (widget, TRUE);
|
||||||
|
|
||||||
if (get_size_groups (widget))
|
if (get_size_groups (widget))
|
||||||
{
|
{
|
||||||
if (aux_info)
|
result = compute_dimension (widget, mode, widget_requisition);
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mark_bumping (widget, FALSE);
|
mark_bumping (widget, FALSE);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@ -217,6 +217,7 @@ compute_size_for_orientation (GtkSizeRequest *request,
|
|||||||
SizeRequest *cached_size;
|
SizeRequest *cached_size;
|
||||||
GtkWidget *widget;
|
GtkWidget *widget;
|
||||||
gboolean found_in_cache = FALSE;
|
gboolean found_in_cache = FALSE;
|
||||||
|
int adjusted_min, adjusted_natural;
|
||||||
|
|
||||||
g_return_if_fail (GTK_IS_SIZE_REQUEST (request));
|
g_return_if_fail (GTK_IS_SIZE_REQUEST (request));
|
||||||
g_return_if_fail (minimum_size != NULL || natural_size != NULL);
|
g_return_if_fail (minimum_size != NULL || natural_size != NULL);
|
||||||
@ -312,12 +313,45 @@ compute_size_for_orientation (GtkSizeRequest *request,
|
|||||||
GTK_PRIVATE_UNSET_FLAG (request, GTK_HEIGHT_REQUEST_NEEDED);
|
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
|
/* Get size groups to compute the base requisition once one
|
||||||
* of the values have been cached, then go ahead and update
|
* of the values have been cached, then go ahead and update
|
||||||
* the cache with the sizegroup computed value.
|
* the cache with the sizegroup computed value.
|
||||||
*
|
|
||||||
* Note this is also where values from gtk_widget_set_size_request()
|
|
||||||
* are considered.
|
|
||||||
*/
|
*/
|
||||||
group_size =
|
group_size =
|
||||||
_gtk_size_group_bump_requisition (GTK_WIDGET (request),
|
_gtk_size_group_bump_requisition (GTK_WIDGET (request),
|
||||||
|
|||||||
@ -315,7 +315,7 @@ static void gtk_widget_real_unrealize (GtkWidget *widget);
|
|||||||
static void gtk_widget_real_size_request (GtkWidget *widget,
|
static void gtk_widget_real_size_request (GtkWidget *widget,
|
||||||
GtkRequisition *requisition);
|
GtkRequisition *requisition);
|
||||||
static void gtk_widget_real_size_allocate (GtkWidget *widget,
|
static void gtk_widget_real_size_allocate (GtkWidget *widget,
|
||||||
GtkAllocation *allocation);
|
GtkAllocation *allocation);
|
||||||
static void gtk_widget_real_style_set (GtkWidget *widget,
|
static void gtk_widget_real_style_set (GtkWidget *widget,
|
||||||
GtkStyle *previous_style);
|
GtkStyle *previous_style);
|
||||||
static void gtk_widget_real_direction_changed(GtkWidget *widget,
|
static void gtk_widget_real_direction_changed(GtkWidget *widget,
|
||||||
@ -408,7 +408,16 @@ static void gtk_widget_real_get_height (GtkSizeRequest
|
|||||||
gint *natural_size);
|
gint *natural_size);
|
||||||
|
|
||||||
static void gtk_widget_queue_tooltip_query (GtkWidget *widget);
|
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,
|
static void gtk_widget_set_usize_internal (GtkWidget *widget,
|
||||||
gint width,
|
gint width,
|
||||||
gint height);
|
gint height);
|
||||||
@ -622,6 +631,9 @@ gtk_widget_class_init (GtkWidgetClass *klass)
|
|||||||
|
|
||||||
klass->no_expose_event = NULL;
|
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,
|
g_object_class_install_property (gobject_class,
|
||||||
PROP_NAME,
|
PROP_NAME,
|
||||||
g_param_spec_string ("name",
|
g_param_spec_string ("name",
|
||||||
@ -3969,7 +3981,11 @@ gtk_widget_queue_shallow_draw (GtkWidget *widget)
|
|||||||
* @allocation: (inout): position and size to be allocated to @widget
|
* @allocation: (inout): position and size to be allocated to @widget
|
||||||
*
|
*
|
||||||
* This function is only used by #GtkContainer subclasses, to assign a size
|
* 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
|
void
|
||||||
gtk_widget_size_allocate (GtkWidget *widget,
|
gtk_widget_size_allocate (GtkWidget *widget,
|
||||||
@ -3978,6 +3994,7 @@ gtk_widget_size_allocate (GtkWidget *widget,
|
|||||||
GtkWidgetPrivate *priv;
|
GtkWidgetPrivate *priv;
|
||||||
GdkRectangle real_allocation;
|
GdkRectangle real_allocation;
|
||||||
GdkRectangle old_allocation;
|
GdkRectangle old_allocation;
|
||||||
|
GdkRectangle adjusted_allocation;
|
||||||
gboolean alloc_needed;
|
gboolean alloc_needed;
|
||||||
gboolean size_changed;
|
gboolean size_changed;
|
||||||
gboolean position_changed;
|
gboolean position_changed;
|
||||||
@ -4016,6 +4033,27 @@ gtk_widget_size_allocate (GtkWidget *widget,
|
|||||||
old_allocation = priv->allocation;
|
old_allocation = priv->allocation;
|
||||||
real_allocation = *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)
|
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",
|
g_warning ("gtk_widget_size_allocate(): attempt to allocate widget with width %d and height %d",
|
||||||
@ -4270,6 +4308,16 @@ gtk_widget_real_size_allocate (GtkWidget *widget,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gtk_widget_real_adjust_size_allocation (GtkWidget *widget,
|
||||||
|
GtkAllocation *allocation)
|
||||||
|
{
|
||||||
|
/* We have no adjustments by default for now, but we have this empty
|
||||||
|
* function here so subclasses can chain up in case we do add
|
||||||
|
* something.
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gtk_widget_real_can_activate_accel (GtkWidget *widget,
|
gtk_widget_real_can_activate_accel (GtkWidget *widget,
|
||||||
guint signal_id)
|
guint signal_id)
|
||||||
@ -9054,6 +9102,35 @@ gtk_widget_real_size_request (GtkWidget *widget,
|
|||||||
requisition->height = 0;
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* _gtk_widget_peek_colormap:
|
* _gtk_widget_peek_colormap:
|
||||||
*
|
*
|
||||||
|
|||||||
@ -473,6 +473,15 @@ struct _GtkWidgetClass
|
|||||||
gint y,
|
gint y,
|
||||||
gboolean keyboard_tooltip,
|
gboolean keyboard_tooltip,
|
||||||
GtkTooltip *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:
|
/* Signals without a C default handler class slot:
|
||||||
* gboolean (*damage_event) (GtkWidget *widget,
|
* gboolean (*damage_event) (GtkWidget *widget,
|
||||||
* GdkEventExpose *event);
|
* GdkEventExpose *event);
|
||||||
|
|||||||
Reference in New Issue
Block a user