diff options
Diffstat (limited to 'gtk')
-rw-r--r-- | gtk/Makefile.am | 2 | ||||
-rw-r--r-- | gtk/gtk.h | 1 | ||||
-rw-r--r-- | gtk/gtkcontainer.c | 34 | ||||
-rw-r--r-- | gtk/gtksignal.c | 5 | ||||
-rw-r--r-- | gtk/gtksizegroup.c | 679 | ||||
-rw-r--r-- | gtk/gtksizegroup.h | 100 | ||||
-rw-r--r-- | gtk/gtkviewport.c | 4 | ||||
-rw-r--r-- | gtk/gtkwidget.c | 32 |
8 files changed, 799 insertions, 58 deletions
diff --git a/gtk/Makefile.am b/gtk/Makefile.am index 1eaa30036..50d2261f3 100644 --- a/gtk/Makefile.am +++ b/gtk/Makefile.am @@ -142,6 +142,7 @@ gtk_public_h_sources = @STRIP_BEGIN@ \ gtkseparator.h \ gtksettings.h \ gtksignal.h \ + gtksizegroup.h \ gtksocket.h \ gtkspinbutton.h \ gtkstyle.h \ @@ -301,6 +302,7 @@ gtk_c_sources = @STRIP_BEGIN@ \ gtkseparator.c \ gtksettings.c \ gtksignal.c \ + gtksizegroup.c \ gtkspinbutton.c \ gtkstock.c \ gtkstyle.c \ @@ -125,6 +125,7 @@ #include <gtk/gtkseparatormenuitem.h> #include <gtk/gtksettings.h> #include <gtk/gtksignal.h> +#include <gtk/gtksizegroup.h> #include <gtk/gtksocket.h> #include <gtk/gtkspinbutton.h> #include <gtk/gtkstock.h> diff --git a/gtk/gtkcontainer.c b/gtk/gtkcontainer.c index 3c80e9a69..2029e7f16 100644 --- a/gtk/gtkcontainer.c +++ b/gtk/gtkcontainer.c @@ -49,7 +49,6 @@ enum { PROP_BORDER_WIDTH, PROP_RESIZE_MODE, PROP_CHILD, - PROP_REALLOCATE_REDRAWS }; typedef struct _GtkChildArgInfo GtkChildArgInfo; @@ -200,13 +199,7 @@ gtk_container_class_init (GtkContainerClass *class) _("Can be used to add a new child to the container."), GTK_TYPE_WIDGET, G_PARAM_WRITABLE)); - g_object_class_install_property (gobject_class, - PROP_REALLOCATE_REDRAWS, - g_param_spec_boolean ("reallocate_redraws", - _("Reallocate redraws"), - _("Whether redraws should be reallocated"), - FALSE, - G_PARAM_READWRITE)); + object_class->destroy = gtk_container_destroy; widget_class->show_all = gtk_container_show_all; @@ -689,10 +682,6 @@ gtk_container_set_property (GObject *object, case PROP_RESIZE_MODE: gtk_container_set_resize_mode (container, g_value_get_enum (value)); break; - case PROP_REALLOCATE_REDRAWS: - gtk_container_set_reallocate_redraws (container, - g_value_get_boolean (value)); - break; case PROP_CHILD: gtk_container_add (container, GTK_WIDGET (g_value_get_object (value))); break; @@ -720,9 +709,6 @@ gtk_container_get_property (GObject *object, case PROP_RESIZE_MODE: g_value_set_enum (value, container->resize_mode); break; - case PROP_REALLOCATE_REDRAWS: - g_value_set_boolean (value, container->reallocate_redraws); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -889,15 +875,7 @@ gtk_container_set_reallocate_redraws (GtkContainer *container, { g_return_if_fail (GTK_IS_CONTAINER (container)); - needs_redraws = needs_redraws ? TRUE : FALSE; - if (needs_redraws != container->reallocate_redraws) - { - container->reallocate_redraws = needs_redraws; - g_object_notify (G_OBJECT (container), "reallocate_redraws"); - - if (container->reallocate_redraws) - gtk_widget_queue_draw (GTK_WIDGET (container)); - } + container->reallocate_redraws = needs_redraws ? TRUE : FALSE; } static GtkContainer* @@ -1092,7 +1070,7 @@ gtk_container_resize_children (GtkContainer *container) /* we first check out if we actually need to perform a resize, * which is not the case if we got another container queued for - * a resize in our anchestry. also we can skip the whole + * a resize in our ancestry. also we can skip the whole * resize_widgets checks if we are a toplevel and NEED_RESIZE. * this code assumes that our allocation is sufficient for our * requisition, since otherwise we would NEED_RESIZE. @@ -1119,7 +1097,7 @@ gtk_container_resize_children (GtkContainer *container) resize_container = GTK_WIDGET (container); - /* we now walk the anchestry for all resize widgets as long + /* we now walk the ancestry for all resize widgets as long * as they are our children and as long as their allocation * is insufficient, since we don't need to reallocate below that. */ @@ -1141,9 +1119,9 @@ gtk_container_resize_children (GtkContainer *container) } /* for the newly setup resize_widgets list, we now walk each widget's - * anchestry to sort those widgets out that have RESIZE_NEEDED parents. + * ancestry to sort those widgets out that have RESIZE_NEEDED parents. * we can safely stop the walk if we are the parent, since we checked - * our own anchestry already. + * our own ancestry already. */ resize_containers = NULL; for (node = resize_widgets; node; node = node->next) diff --git a/gtk/gtksignal.c b/gtk/gtksignal.c index 54a6c14f3..b7ed0fb1f 100644 --- a/gtk/gtksignal.c +++ b/gtk/gtksignal.c @@ -321,11 +321,12 @@ gtk_signal_emitv (GtkObject *object, GValue *value = params + 1 + i; GtkArg *arg = args + i; - g_value_init (value, arg->type); + g_value_init (value, arg->type & ~G_SIGNAL_TYPE_STATIC_SCOPE); if (!gtk_arg_static_to_value (arg, value)) { g_warning ("%s: failed to convert arg type `%s' to value type `%s'", - G_STRLOC, g_type_name (arg->type), g_type_name (G_VALUE_TYPE (value))); + G_STRLOC, g_type_name (arg->type & ~G_SIGNAL_TYPE_STATIC_SCOPE), + g_type_name (G_VALUE_TYPE (value))); return; } } diff --git a/gtk/gtksizegroup.c b/gtk/gtksizegroup.c new file mode 100644 index 000000000..ccd710068 --- /dev/null +++ b/gtk/gtksizegroup.c @@ -0,0 +1,679 @@ +/* GTK - The GIMP Toolkit + * gtksizegroup.c: + * Copyright (C) 2001 Red Hat Software + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser 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 "gtkcontainer.h" +#include "gtkintl.h" +#include "gtksignal.h" +#include "gtksizegroup.h" + +enum { + PROP_0, + PROP_MODE +}; + +static void gtk_size_group_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void gtk_size_group_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); + +static void add_group_to_closure (GtkSizeGroup *group, + GtkSizeGroupMode mode, + GSList **groups, + GSList **widgets); +static void add_widget_to_closure (GtkWidget *widget, + GtkSizeGroupMode mode, + GSList **groups, + GSList **widgets); + +static GQuark size_groups_quark; +static const gchar *size_groups_tag = "gtk-size-groups"; + +static GSList * +get_size_groups (GtkWidget *widget) +{ + if (!size_groups_quark) + size_groups_quark = g_quark_from_string (size_groups_tag); + + return g_object_get_qdata (G_OBJECT (widget), size_groups_quark); +} + +static void +set_size_groups (GtkWidget *widget, + GSList *groups) +{ + if (!size_groups_quark) + size_groups_quark = g_quark_from_string (size_groups_tag); + + g_object_set_qdata (G_OBJECT (widget), size_groups_quark, groups); +} + +static void +add_group_to_closure (GtkSizeGroup *group, + GtkSizeGroupMode mode, + GSList **groups, + GSList **widgets) +{ + GSList *tmp_widgets; + + *groups = g_slist_prepend (*groups, group); + + tmp_widgets = group->widgets; + while (tmp_widgets) + { + GtkWidget *tmp_widget = tmp_widgets->data; + + if (!g_slist_find (*widgets, tmp_widget)) + add_widget_to_closure (tmp_widget, mode, groups, widgets); + + tmp_widgets = tmp_widgets->next; + } +} + +static void +add_widget_to_closure (GtkWidget *widget, + GtkSizeGroupMode mode, + GSList **groups, + GSList **widgets) +{ + GSList *tmp_groups; + + *widgets = g_slist_prepend (*widgets, widget); + + tmp_groups = get_size_groups (widget); + while (tmp_groups) + { + GtkSizeGroup *tmp_group = tmp_groups->data; + + if ((tmp_group->mode == GTK_SIZE_GROUP_BOTH || tmp_group->mode == mode) && + !g_slist_find (*groups, tmp_group)) + add_group_to_closure (tmp_group, mode, groups, widgets); + + tmp_groups = tmp_groups->next; + } +} + +static void +real_queue_resize (GtkWidget *widget) +{ + if (GTK_IS_RESIZE_CONTAINER (widget)) + gtk_container_clear_resize_widgets (GTK_CONTAINER (widget)); + + if (widget->parent) + gtk_container_queue_resize (GTK_CONTAINER (widget->parent)); + else if (GTK_WIDGET_TOPLEVEL (widget) && GTK_IS_CONTAINER (widget)) + gtk_container_queue_resize (GTK_CONTAINER (widget)); +} + +static void +reset_group_sizes (GSList *groups) +{ + GSList *tmp_list = groups; + while (tmp_list) + { + GtkSizeGroup *tmp_group = tmp_list->data; + + tmp_group->have_width = FALSE; + tmp_group->have_height = FALSE; + + tmp_list = tmp_list->next; + } +} + +static void +queue_resize_on_widget (GtkWidget *widget, + gboolean check_siblings) +{ + GtkWidget *parent = widget; + GSList *tmp_list; + + while (parent) + { + GSList *widget_groups; + GSList *groups; + GSList *widgets; + + if (widget == parent && !check_siblings) + { + real_queue_resize (widget); + parent = parent->parent; + continue; + } + + widget_groups = get_size_groups (parent); + if (!widget_groups) + { + if (widget == parent) + real_queue_resize (widget); + + parent = parent->parent; + continue; + } + + groups = NULL; + widgets = NULL; + + add_widget_to_closure (parent, GTK_SIZE_GROUP_HORIZONTAL, &groups, &widgets); + reset_group_sizes (groups); + + tmp_list = widgets; + while (tmp_list) + { + if (tmp_list->data == parent) + { + if (widget == parent) + real_queue_resize (parent); + } + else + queue_resize_on_widget (tmp_list->data, FALSE); + + tmp_list = tmp_list->next; + } + + g_slist_free (widgets); + g_slist_free (groups); + + groups = NULL; + widgets = NULL; + + add_widget_to_closure (parent, GTK_SIZE_GROUP_VERTICAL, &groups, &widgets); + reset_group_sizes (groups); + + tmp_list = widgets; + while (tmp_list) + { + if (tmp_list->data == parent) + { + if (widget == parent) + real_queue_resize (parent); + } + else + queue_resize_on_widget (tmp_list->data, FALSE); + + tmp_list = tmp_list->next; + } + + g_slist_free (widgets); + g_slist_free (groups); + + parent = parent->parent; + } +} + +static void +queue_resize_on_group (GtkSizeGroup *size_group) +{ + if (size_group->widgets) + queue_resize_on_widget (size_group->widgets->data, TRUE); +} + +static void +gtk_size_group_class_init (GtkSizeGroupClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->set_property = gtk_size_group_set_property; + gobject_class->get_property = gtk_size_group_get_property; + + g_object_class_install_property (gobject_class, + PROP_MODE, + g_param_spec_enum ("mode", + _("Mode"), + _("The the directions in which the size group effects the requested sizes" + " of its component widgets."), + GTK_TYPE_SIZE_GROUP_MODE, + GTK_SIZE_GROUP_HORIZONTAL, + G_PARAM_READWRITE)); +} + +static void +gtk_size_group_init (GtkSizeGroup *size_group) +{ + size_group->widgets = NULL; + size_group->mode = GTK_SIZE_GROUP_HORIZONTAL; + size_group->have_width = 0; + size_group->have_height = 0; +} + +GtkType +gtk_size_group_get_type (void) +{ + static GtkType size_group_type = 0; + + if (!size_group_type) + { + static const GTypeInfo size_group_info = + { + sizeof (GtkSizeGroupClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) gtk_size_group_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (GtkSizeGroup), + 16, /* n_preallocs */ + (GInstanceInitFunc) gtk_size_group_init, + }; + + size_group_type = g_type_register_static (G_TYPE_OBJECT, "GtkSizeGroup", &size_group_info, 0); + } + + return size_group_type; +} + +static void +gtk_size_group_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GtkSizeGroup *size_group = GTK_SIZE_GROUP (object); + + switch (prop_id) + { + case PROP_MODE: + gtk_size_group_set_mode (size_group, g_value_get_enum (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gtk_size_group_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GtkSizeGroup *size_group = GTK_SIZE_GROUP (object); + + switch (prop_id) + { + case PROP_MODE: + g_value_set_enum (value, size_group->mode); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +/** + * gtk_size_group_new: + * @mode: the mode for the new size group. + * + * Create a new #GtkSizeGroup. + + * Return value: a newly created #GtkSizeGroup + **/ +GtkSizeGroup * +gtk_size_group_new (GtkSizeGroupMode mode) +{ + GtkSizeGroup *size_group = g_object_new (GTK_TYPE_SIZE_GROUP, NULL); + + size_group->mode = mode; + + return size_group; +} + +/** + * gtk_size_group_set_mode: + * @size_group: a #GtkSizeGroup + * @mode: the mode to set for the size group. + * + * Sets the #GtkSizeGroupMode of the size group. The mode of the size + * group determines whether the widgets in the size group should + * all have the same horizontal requisition (%GTK_SIZE_GROUP_MODE_HORIZONTAL) + * all have the same vertical requisition (%GTK_SIZE_GROUP_MODE_VERTICAL), + * or should all have the same requisition in both directions. + * (%GTK_SIZE_GROUP_MODE_BOTH). + **/ +void +gtk_size_group_set_mode (GtkSizeGroup *size_group, + GtkSizeGroupMode mode) +{ + g_return_if_fail (GTK_IS_SIZE_GROUP (size_group)); + + if (size_group->mode != mode) + { + size_group->mode = mode; + queue_resize_on_group (size_group); + } +} + +/** + * gtk_size_group_get_mode: + * @size_group: a #GtkSizeGroup + * + * Gets the current mode of the size group. See gtk_size_group_set_mode(). + * + * Return value: the current mode of the size group. + **/ +GtkSizeGroupMode +gtk_size_group_get_mode (GtkSizeGroup *size_group) +{ + g_return_val_if_fail (GTK_IS_SIZE_GROUP (size_group), GTK_SIZE_GROUP_BOTH); + + return size_group->mode; +} + +static void +gtk_size_group_widget_destroyed (GtkWidget *widget, + GtkSizeGroup *size_group) +{ + gtk_size_group_remove_widget (size_group, widget); +} + +/** + * gtk_size_group_add_widget: + * @size_group: a #GtkSizeGroup + * @widget: the #GtkWidget to add + * + * Adds a widget to a #GtkSizeGroup. In the future, the requisition + * of the widget will be determined as the maximum of its requisition + * and the requisition of the other widgets in the size group. + * Whether this applies horizontally, vertically, or in both directions + * depends on the mode of the size group. See gtk_size_group_set_mode(). + **/ +void +gtk_size_group_add_widget (GtkSizeGroup *size_group, + GtkWidget *widget) +{ + GSList *groups; + + g_return_if_fail (GTK_IS_SIZE_GROUP (size_group)); + g_return_if_fail (GTK_IS_WIDGET (widget)); + + groups = get_size_groups (widget); + + if (!g_slist_find (groups, widget)) + { + groups = g_slist_prepend (groups, size_group); + set_size_groups (widget, groups); + + size_group->widgets = g_slist_prepend (size_group->widgets, widget); + + gtk_signal_connect (GTK_OBJECT (widget), "destroy", + GTK_SIGNAL_FUNC (gtk_size_group_widget_destroyed), size_group); + + g_object_ref (G_OBJECT (size_group)); + } + + queue_resize_on_group (size_group); +} + +/** + * gtk_size_group_remove_widget: + * @size_group: a #GtkSizeGrup + * @widget: the #GtkWidget to remove + * + * Removes a widget from a #GtkSizeGroup. + **/ +void +gtk_size_group_remove_widget (GtkSizeGroup *size_group, + GtkWidget *widget) +{ + GSList *groups; + + g_return_if_fail (GTK_IS_SIZE_GROUP (size_group)); + g_return_if_fail (GTK_IS_WIDGET (widget)); + g_return_if_fail (g_slist_find (size_group->widgets, widget)); + + gtk_signal_disconnect_by_func (GTK_OBJECT (widget), + GTK_SIGNAL_FUNC (gtk_size_group_widget_destroyed), size_group); + + groups = get_size_groups (widget); + groups = g_slist_remove (groups, size_group); + set_size_groups (widget, groups); + + size_group->widgets = g_slist_remove (size_group->widgets, widget); + queue_resize_on_group (size_group); + gtk_widget_queue_resize (widget); + + g_object_unref (G_OBJECT (size_group)); +} + +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 + return widget->requisition.width; + } + else + { + if (aux_info && aux_info->height > 0) + return aux_info->height; + else + return widget->requisition.height; + } +} + +static gint +compute_base_dimension (GtkWidget *widget, + GtkSizeGroupMode mode) +{ + gtk_widget_ensure_style (widget); + gtk_signal_emit_by_name (GTK_OBJECT (widget), "size_request", &widget->requisition); + + return get_base_dimension (widget, mode); +} + +static gint +compute_dimension (GtkWidget *widget, + GtkSizeGroupMode mode) +{ + GSList *widgets = NULL; + GSList *groups = NULL; + GSList *tmp_list; + gint result = 0; + + add_widget_to_closure (widget, mode, &groups, &widgets); + + g_slist_foreach (widgets, (GFunc)g_object_ref, NULL); + + if (!groups) + { + result = compute_base_dimension (widget, mode); + } + else + { + GtkSizeGroup *group = groups->data; + + if (mode == GTK_SIZE_GROUP_HORIZONTAL && group->have_width) + result = group->requisition.width; + else if (mode == GTK_SIZE_GROUP_VERTICAL && group->have_height) + result = group->requisition.height; + else + { + tmp_list = widgets; + while (tmp_list) + { + GtkWidget *tmp_widget = tmp_list->data; + + gint dimension = compute_base_dimension (tmp_widget, mode); + + if (dimension > result) + result = dimension; + + tmp_list = tmp_list->next; + } + + tmp_list = groups; + while (tmp_list) + { + GtkSizeGroup *tmp_group = tmp_list->data; + + if (mode == GTK_SIZE_GROUP_HORIZONTAL) + { + tmp_group->have_width = TRUE; + tmp_group->requisition.width = result; + } + else + { + tmp_group->have_height = TRUE; + tmp_group->requisition.height = result; + } + + tmp_list = tmp_list->next; + } + } + } + + g_slist_foreach (widgets, (GFunc)g_object_unref, NULL); + + g_slist_free (widgets); + g_slist_free (groups); + + return result; +} + +static gint +get_dimension (GtkWidget *widget, + GtkSizeGroupMode mode) +{ + GSList *widgets = NULL; + GSList *groups = NULL; + gint result = 0; + + add_widget_to_closure (widget, mode, &groups, &widgets); + + if (!groups) + { + result = get_base_dimension (widget, mode); + } + else + { + GtkSizeGroup *group = groups->data; + + if (mode == GTK_SIZE_GROUP_HORIZONTAL && group->have_width) + result = group->requisition.width; + else if (mode == GTK_SIZE_GROUP_VERTICAL && group->have_height) + result = group->requisition.height; + } + + g_slist_free (widgets); + g_slist_free (groups); + + return result; +} + +static void +get_fast_child_requisition (GtkWidget *widget, + GtkRequisition *requisition) +{ + GtkWidgetAuxInfo *aux_info = _gtk_widget_get_aux_info (widget, FALSE); + + *requisition = widget->requisition; + + if (aux_info) + { + if (aux_info->width > 0) + requisition->width = aux_info->width; + if (aux_info && aux_info->height > 0) + requisition->height = aux_info->height; + } +} + +/** + * _gtk_size_group_get_child_requisition: + * @widget: a #GtkWidget + * @requisition: location to store computed requisition. + * + * Retrieve the "child requisition" of the widget, taking account grouping + * of the widget's requisition with other widgets. + **/ +void +_gtk_size_group_get_child_requisition (GtkWidget *widget, + GtkRequisition *requisition) +{ + if (requisition) + { + if (get_size_groups (widget)) + { + requisition->width = get_dimension (widget, GTK_SIZE_GROUP_HORIZONTAL); + requisition->height = get_dimension (widget, GTK_SIZE_GROUP_VERTICAL); + + /* Only do the full computation if we actually have size groups */ + } + else + get_fast_child_requisition (widget, requisition); + } +} + +/** + * _gtk_size_group_compute_requisition: + * @widget: a #GtkWidget + * @requisition: location to store computed requisition. + * + * Compute the requisition of a widget taking into account grouping of + * the widget's requisition with other widgets. + **/ +void +_gtk_size_group_compute_requisition (GtkWidget *widget, + GtkRequisition *requisition) +{ + gint width; + gint height; + + if (get_size_groups (widget)) + { + /* Only do the full computation if we actually have size groups */ + + width = compute_dimension (widget, GTK_SIZE_GROUP_HORIZONTAL); + height = compute_dimension (widget, GTK_SIZE_GROUP_VERTICAL); + + if (requisition) + { + requisition->width = width; + requisition->height = height; + } + } + else + { + gtk_widget_ensure_style (widget); + gtk_signal_emit_by_name (GTK_OBJECT (widget), "size_request", &widget->requisition); + + if (requisition) + get_fast_child_requisition (widget, requisition); + } +} + +/** + * _gtk_size_group_queue_resize: + * @widget: a #GtkWidget + * + * Queue a resize on a widget, and on all other widgets grouped with this widget. + **/ +void +_gtk_size_group_queue_resize (GtkWidget *widget) +{ + queue_resize_on_widget (widget, TRUE); +} diff --git a/gtk/gtksizegroup.h b/gtk/gtksizegroup.h new file mode 100644 index 000000000..32d3ec21a --- /dev/null +++ b/gtk/gtksizegroup.h @@ -0,0 +1,100 @@ +/* GTK - The GIMP Toolkit + * gtksizegroup.h: + * Copyright (C) 2000 Red Hat Software + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser 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. + */ + +#ifndef __GTK_SIZE_GROUP_H__ +#define __GTK_SIZE_GROUP_H__ + +#include <gtk/gtkwidget.h> + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define GTK_TYPE_SIZE_GROUP (gtk_size_group_get_type ()) +#define GTK_SIZE_GROUP(obj) (GTK_CHECK_CAST ((obj), GTK_TYPE_SIZE_GROUP, GtkSizeGroup)) +#define GTK_SIZE_GROUP_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), GTK_TYPE_SIZE_GROUP, GtkSizeGroupClass)) +#define GTK_IS_SIZE_GROUP(obj) (GTK_CHECK_TYPE ((obj), GTK_TYPE_SIZE_GROUP)) +#define GTK_IS_SIZE_GROUP_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GTK_TYPE_SIZE_GROUP)) +#define GTK_SIZE_GROUP_GET_CLASS(obj) (GTK_CHECK_GET_CLASS ((obj), GTK_TYPE_SIZE_GROUP, GtkSizeGroupClass)) + + +typedef struct _GtkSizeGroup GtkSizeGroup; +typedef struct _GtkSizeGroupClass GtkSizeGroupClass; + +struct _GtkSizeGroup +{ + GObject parent_instance; + + GSList *widgets; + + guint8 mode; + + guint have_width : 1; + guint have_height : 1; + + GtkRequisition requisition; +}; + +struct _GtkSizeGroupClass +{ + GObjectClass parent_class; +}; + +/** + * GtkSizeGroupMode: + * @GTK_SIZE_GROUP_NONE: group has no effect + * @GTK_SIZE_GROUP_HORIZONTAL: group effects horizontal requisition + * @GTK_SIZE_GROUP_VERTICAL: group effects vertical requisition + * @GTK_SIZE_GROUP_BOTH: group effects both horizontal and vertical requisition + * + * The mode of the size group determines the directions in which the size + * group effects the requested sizes of its component widgets. + **/ +typedef enum { + GTK_SIZE_GROUP_NONE, + GTK_SIZE_GROUP_HORIZONTAL, + GTK_SIZE_GROUP_VERTICAL, + GTK_SIZE_GROUP_BOTH +} GtkSizeGroupMode; + +GType gtk_size_group_get_type (void) G_GNUC_CONST;; + +GtkSizeGroup * gtk_size_group_new (GtkSizeGroupMode mode); +void gtk_size_group_set_mode (GtkSizeGroup *size_group, + GtkSizeGroupMode type); +GtkSizeGroupMode gtk_size_group_get_mode (GtkSizeGroup *size_group); +void gtk_size_group_add_widget (GtkSizeGroup *size_group, + GtkWidget *widget); +void gtk_size_group_remove_widget (GtkSizeGroup *size_group, + GtkWidget *widget); + + +void _gtk_size_group_get_child_requisition (GtkWidget *widget, + GtkRequisition *requisition); +void _gtk_size_group_compute_requisition (GtkWidget *widget, + GtkRequisition *requisition); +void _gtk_size_group_queue_resize (GtkWidget *widget); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + +#endif /* __GTK_SIZE_GROUP_H__ */ diff --git a/gtk/gtkviewport.c b/gtk/gtkviewport.c index c370e9d2b..34dd90c80 100644 --- a/gtk/gtkviewport.c +++ b/gtk/gtkviewport.c @@ -203,10 +203,10 @@ gtk_viewport_get_property (GObject *object, switch (prop_id) { case PROP_HADJUSTMENT: - g_value_set_object (value, viewport->hadjustment); + g_value_set_object (value, G_OBJECT (viewport->hadjustment)); break; case PROP_VADJUSTMENT: - g_value_set_object (value, viewport->vadjustment); + g_value_set_object (value, G_OBJECT (viewport->vadjustment)); break; case PROP_SHADOW_TYPE: g_value_set_enum (value, viewport->shadow_type); diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c index 345b430db..dd09db96c 100644 --- a/gtk/gtkwidget.c +++ b/gtk/gtkwidget.c @@ -34,6 +34,7 @@ #include "gtkrc.h" #include "gtkselection.h" #include "gtksettings.h" +#include "gtksizegroup.h" #include "gtksignal.h" #include "gtkwidget.h" #include "gtkwindow.h" @@ -2081,15 +2082,9 @@ gtk_widget_queue_resize (GtkWidget *widget) g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_WIDGET (widget)); - if (GTK_IS_RESIZE_CONTAINER (widget)) - gtk_container_clear_resize_widgets (GTK_CONTAINER (widget)); - gtk_widget_queue_clear (widget); - if (widget->parent) - gtk_container_queue_resize (GTK_CONTAINER (widget->parent)); - else if (GTK_WIDGET_TOPLEVEL (widget) && GTK_IS_CONTAINER (widget)) - gtk_container_queue_resize (GTK_CONTAINER (widget)); + _gtk_size_group_queue_resize (widget); } /** @@ -2149,15 +2144,14 @@ gtk_widget_size_request (GtkWidget *widget, g_warning ("gtk_widget_size_request() called on child widget with request equal\n to widget->requisition. gtk_widget_set_usize() may not work properly."); #endif /* G_ENABLE_DEBUG */ - gtk_widget_ref (widget); - gtk_widget_ensure_style (widget); - gtk_signal_emit (GTK_OBJECT (widget), widget_signals[SIZE_REQUEST], - &widget->requisition); + _gtk_size_group_compute_requisition (widget, requisition); +#if 0 if (requisition) gtk_widget_get_child_requisition (widget, requisition); gtk_widget_unref (widget); +#endif } /** @@ -2174,21 +2168,7 @@ void gtk_widget_get_child_requisition (GtkWidget *widget, GtkRequisition *requisition) { - GtkWidgetAuxInfo *aux_info; - - g_return_if_fail (widget != NULL); - g_return_if_fail (GTK_IS_WIDGET (widget)); - - *requisition = widget->requisition; - - aux_info =_gtk_widget_get_aux_info (widget, FALSE); - if (aux_info) - { - if (aux_info->width > 0) - requisition->width = aux_info->width; - if (aux_info->height > 0) - requisition->height = aux_info->height; - } + _gtk_size_group_get_child_requisition (widget, requisition); } /** |