diff options
author | Havoc Pennington <hp@pobox.com> | 2010-09-05 12:19:14 -0400 |
---|---|---|
committer | Havoc Pennington <hp@pobox.com> | 2010-09-12 13:12:16 -0400 |
commit | a171c499c3e9f5cf8befb1aacb389b94178b2ae4 (patch) | |
tree | 6fd3ed129316cb40592371d51983ec81012c7d1f | |
parent | d2243056e5ecea620359d097375622ff1ffcdc9e (diff) | |
download | gtk+-a171c499c3e9f5cf8befb1aacb389b94178b2ae4.tar.gz |
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.
-rw-r--r-- | gtk/gtksizegroup.c | 49 | ||||
-rw-r--r-- | gtk/gtksizerequest.c | 40 | ||||
-rw-r--r-- | gtk/gtkwidget.c | 83 | ||||
-rw-r--r-- | gtk/gtkwidget.h | 9 |
4 files changed, 136 insertions, 45 deletions
diff --git a/gtk/gtksizegroup.c b/gtk/gtksizegroup.c index 59ddc6e985..cc16476e81 100644 --- a/gtk/gtksizegroup.c +++ b/gtk/gtksizegroup.c @@ -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; diff --git a/gtk/gtksizerequest.c b/gtk/gtksizerequest.c index 827265ef29..543bbc140b 100644 --- a/gtk/gtksizerequest.c +++ b/gtk/gtksizerequest.c @@ -217,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); @@ -312,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), diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c index cbb568fa03..874be7eb78 100644 --- a/gtk/gtkwidget.c +++ b/gtk/gtkwidget.c @@ -315,7 +315,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, @@ -408,7 +408,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); @@ -622,6 +631,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", @@ -3969,7 +3981,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, @@ -3978,6 +3994,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; @@ -4016,6 +4033,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", @@ -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 gtk_widget_real_can_activate_accel (GtkWidget *widget, guint signal_id) @@ -9054,6 +9102,35 @@ 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); +} + /** * _gtk_widget_peek_colormap: * diff --git a/gtk/gtkwidget.h b/gtk/gtkwidget.h index b413e0d421..66d3f2737c 100644 --- a/gtk/gtkwidget.h +++ b/gtk/gtkwidget.h @@ -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); |