diff options
author | Havoc Pennington <hp@pobox.com> | 2010-09-05 02:12:10 -0400 |
---|---|---|
committer | Havoc Pennington <hp@pobox.com> | 2010-09-12 13:12:16 -0400 |
commit | 248267badbed6d635ddb433ce6ef189ab6749ab0 (patch) | |
tree | e8a7bde11f6511f43d49cb9cada22d138af2723e | |
parent | 35a666c534a81f088df380ce136477ae7ed28389 (diff) | |
download | gtk+-248267badbed6d635ddb433ce6ef189ab6749ab0.tar.gz |
add gtk_container_class_handle_border_width() so subclasses can ignore border_width
A subclass calls gtk_container_class_handle_border_width()
in its class_init
This marks the subclass as expecting GtkContainer to deal with
border width automatically, which GtkContainer then does.
-rw-r--r-- | gtk/gtkcontainer.c | 109 | ||||
-rw-r--r-- | gtk/gtkcontainer.h | 4 |
2 files changed, 112 insertions, 1 deletions
diff --git a/gtk/gtkcontainer.c b/gtk/gtkcontainer.c index 3599fe0cb8..a4f20efb89 100644 --- a/gtk/gtkcontainer.c +++ b/gtk/gtkcontainer.c @@ -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 diff --git a/gtk/gtkcontainer.h b/gtk/gtkcontainer.h index ff84ac8ff0..f4376759a6 100644 --- a/gtk/gtkcontainer.h +++ b/gtk/gtkcontainer.h @@ -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); |