[gtk+/widget-padding: 6/11] GtkWidget: add adjust_size_request adjust_size_allocation virtual funcs
- From: Havoc Pennington <hp src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/widget-padding: 6/11] GtkWidget: add adjust_size_request adjust_size_allocation virtual funcs
- Date: Wed, 8 Sep 2010 02:10:37 +0000 (UTC)
commit 034a436d3803b29a8938f61970c50f9e21e396ea
Author: Havoc Pennington <hp pobox com>
Date: Sun Sep 5 12:19:14 2010 -0400
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.
gtk/gtksizegroup.c | 49 ++++++-----------------------
gtk/gtksizerequest.c | 40 ++++++++++++++++++++++--
gtk/gtkwidget.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++--
gtk/gtkwidget.h | 9 +++++
4 files changed, 136 insertions(+), 45 deletions(-)
---
diff --git a/gtk/gtksizegroup.c b/gtk/gtksizegroup.c
index 87f5c48..1d20700 100644
--- a/gtk/gtksizegroup.c
+++ b/gtk/gtksizegroup.c
@@ -667,35 +667,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;
}
}
@@ -802,31 +790,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;
diff --git a/gtk/gtksizerequest.c b/gtk/gtksizerequest.c
index 0a5fff9..5322be2 100644
--- a/gtk/gtksizerequest.c
+++ b/gtk/gtksizerequest.c
@@ -272,6 +272,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);
@@ -367,12 +368,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),
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index 1e2f03e..cff9b08 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -264,7 +264,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,
@@ -357,7 +357,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);
@@ -571,6 +580,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",
@@ -3891,7 +3903,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,
@@ -3899,6 +3915,7 @@ gtk_widget_size_allocate (GtkWidget *widget,
{
GdkRectangle real_allocation;
GdkRectangle old_allocation;
+ GdkRectangle adjusted_allocation;
gboolean alloc_needed;
gboolean size_changed;
gboolean position_changed;
@@ -3934,6 +3951,27 @@ gtk_widget_size_allocate (GtkWidget *widget,
old_allocation = widget->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",
@@ -4184,6 +4222,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
gtk_widget_real_can_activate_accel (GtkWidget *widget,
guint signal_id)
@@ -8892,6 +8940,35 @@ gtk_widget_real_size_request (GtkWidget *widget,
requisition->height = widget->requisition.height;
}
+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:
*
diff --git a/gtk/gtkwidget.h b/gtk/gtkwidget.h
index 4b35ca3..8d49485 100644
--- a/gtk/gtkwidget.h
+++ b/gtk/gtkwidget.h
@@ -522,6 +522,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);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]