Refactored GtkSizeGroup for GtkExtendedLayout

Removed _gtk_size_group_compute_requisition and
_gtk_size_group_get_child_requisition in favor of
_gtk_size_group_bump_requisition() which does an orientation
contextual computation of the size group and returns the
collective value in one pass.
This commit is contained in:
Tristan Van Berkom
2010-04-17 01:46:59 -04:00
parent 8432f54c51
commit caba7992b8
3 changed files with 61 additions and 191 deletions

View File

@@ -25,6 +25,7 @@
#include "gtkprivate.h"
#include "gtksizegroup.h"
#include "gtkbuildable.h"
#include "gtkextendedlayout.h"
#include "gtkalias.h"
enum {
@@ -71,6 +72,9 @@ static const gchar size_groups_tag[] = "gtk-size-groups";
static GQuark visited_quark;
static const gchar visited_tag[] = "gtk-size-group-visited";
static GQuark bumping_quark;
static const gchar bumping_tag[] = "gtk-size-group-bumping";
static GSList *
get_size_groups (GtkWidget *widget)
{
@@ -102,6 +106,18 @@ is_visited (gpointer object)
return g_object_get_qdata (object, visited_quark) != NULL;
}
static void
mark_bumping (gpointer object, gboolean bumping)
{
g_object_set_qdata (object, bumping_quark, bumping ? "bumping" : NULL);
}
static gboolean
is_bumping (gpointer object)
{
return g_object_get_qdata (object, bumping_quark) != NULL;
}
static void
add_group_to_closure (GtkSizeGroup *group,
GtkSizeGroupMode mode,
@@ -286,6 +302,7 @@ initialize_size_group_quarks (void)
{
size_groups_quark = g_quark_from_static_string (size_groups_tag);
visited_quark = g_quark_from_static_string (visited_tag);
bumping_quark = g_quark_from_static_string (bumping_tag);
}
}
@@ -609,57 +626,35 @@ get_base_dimension (GtkWidget *widget,
if (aux_info && aux_info->width > 0)
return aux_info->width;
else
return widget->requisition.width;
{
/* XXX Possibly we should be using natural values and not minimums here. */
gint width;
gtk_extended_layout_get_desired_width (GTK_EXTENDED_LAYOUT (widget), &width, NULL);
return width;
}
}
else
{
if (aux_info && aux_info->height > 0)
return aux_info->height;
else
return widget->requisition.height;
{
/* XXX Possibly we should be using natural values and not minimums here. */
gint height;
gtk_extended_layout_get_desired_height (GTK_EXTENDED_LAYOUT (widget), &height, NULL);
return height;
}
}
}
static void
do_size_request (GtkWidget *widget, gint width, gint height)
{
if (GTK_WIDGET_REQUEST_NEEDED (widget))
{
gtk_widget_ensure_style (widget);
GTK_PRIVATE_UNSET_FLAG (widget, GTK_REQUEST_NEEDED);
g_signal_emit_by_name (widget,
"size-request",
&widget->requisition);
}
/* Also update size groups from _gtk_size_group_bump_requisition() */
widget->requisition.width = MAX (widget->requisition.width, width);
widget->requisition.height = MAX (widget->requisition.height, height);
}
/* NOTE: This is only ever called for either mode horizontal or mode vertical
* but never as both.
*/
static gint
compute_base_dimension (GtkWidget *widget,
GtkSizeGroupMode mode,
gint minimum)
{
if (mode == GTK_SIZE_GROUP_HORIZONTAL)
do_size_request (widget, minimum, -1);
else /* (mode == GTK_SIZE_GROUP_VERTICAL) */
do_size_request (widget, -1, minimum);
return get_base_dimension (widget, mode);
}
/* NOTE: This is only ever called for either mode horizontal or mode vertical
* but never as both.
*/
static gint
compute_dimension (GtkWidget *widget,
GtkSizeGroupMode mode,
gint minimum)
gint widget_requisition)
{
GSList *widgets = NULL;
GSList *groups = NULL;
@@ -675,7 +670,7 @@ compute_dimension (GtkWidget *widget,
if (!groups)
{
result = compute_base_dimension (widget, mode, minimum);
result = widget_requisition;
}
else
{
@@ -691,8 +686,12 @@ compute_dimension (GtkWidget *widget,
while (tmp_list)
{
GtkWidget *tmp_widget = tmp_list->data;
gint dimension;
gint dimension = compute_base_dimension (tmp_widget, mode, minimum);
if (tmp_widget == widget)
dimension = widget_requisition;
else
dimension = get_base_dimension (tmp_widget, mode);
if (gtk_widget_get_mapped (tmp_widget) || !group->ignore_hidden)
{
@@ -711,12 +710,12 @@ compute_dimension (GtkWidget *widget,
if (mode == GTK_SIZE_GROUP_HORIZONTAL)
{
tmp_group->have_width = TRUE;
tmp_group->requisition.width = MAX (result, minimum);
tmp_group->requisition.width = result;
}
else
{
tmp_group->have_height = TRUE;
tmp_group->requisition.height = MAX (result, minimum);
tmp_group->requisition.height = result;
}
tmp_list = tmp_list->next;
@@ -732,162 +731,39 @@ compute_dimension (GtkWidget *widget,
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);
g_slist_foreach (widgets, (GFunc)mark_unvisited, NULL);
g_slist_foreach (groups, (GFunc)mark_unvisited, NULL);
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)
{
initialize_size_group_quarks ();
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.
*
* This is used by #GtkExtendedLayout to obtain minimum value
* caps for all values cached and returned to parent containers,
* then the extended layout while making its own sizes in multiple
* passes updates sizegroups with _gtk_size_group_bump_requisition().
*/
void
_gtk_size_group_compute_requisition (GtkWidget *widget,
GtkRequisition *requisition)
{
gint width;
gint height;
initialize_size_group_quarks ();
if (get_size_groups (widget))
{
/* Only do the full computation if we actually have size groups */
width = compute_dimension (widget, GTK_SIZE_GROUP_HORIZONTAL, -1);
height = compute_dimension (widget, GTK_SIZE_GROUP_VERTICAL, -1);
if (requisition)
{
requisition->width = width;
requisition->height = height;
}
}
else
{
do_size_request (widget, -1, -1);
if (requisition)
get_fast_child_requisition (widget, requisition);
}
}
/**
* _gtk_size_group_bump_requisition:
* @widget: a #GtkWidget
* @mode: either %GTK_SIZE_GROUP_HORIZONTAL or %GTK_SIZE_GROUP_VERTICAL, depending
* on the dimension in which to bump the size.
* @size: The new base size in @mode's dimension for the group.
*
* Refreshes the sizegroup while returning the groups requested
* value in the dimension @mode.
*
* This function is used to update sizegroup minimum size information
* in multiple passes from the new #GtkExtendedLayout manager.
*/
void
gint
_gtk_size_group_bump_requisition (GtkWidget *widget,
GtkSizeGroupMode mode,
gint size)
gint widget_requisition)
{
initialize_size_group_quarks ();
gint result = widget_requisition;
if (get_size_groups (widget))
if (!is_bumping (widget) && get_size_groups (widget))
{
if (mode == GTK_SIZE_GROUP_HORIZONTAL)
compute_dimension (widget, GTK_SIZE_GROUP_HORIZONTAL, size);
else
compute_dimension (widget, GTK_SIZE_GROUP_VERTICAL, size);
}
else
{
if (mode == GTK_SIZE_GROUP_HORIZONTAL)
do_size_request (widget, size, -1);
else
do_size_request (widget, -1, size);
/* Avoid recursion here */
mark_bumping (widget, TRUE);
result = compute_dimension (widget, mode, widget_requisition);
mark_bumping (widget, FALSE);
}
return result;
}
/**
* _gtk_size_group_queue_resize:
* @widget: a #GtkWidget

View File

@@ -100,13 +100,10 @@ void gtk_size_group_remove_widget (GtkSizeGroup *size_group,
GSList * gtk_size_group_get_widgets (GtkSizeGroup *size_group);
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_bump_requisition (GtkWidget *widget,
gint _gtk_size_group_bump_requisition (GtkWidget *widget,
GtkSizeGroupMode mode,
gint size);
gint widget_requisition);
void _gtk_size_group_queue_resize (GtkWidget *widget);

View File

@@ -3928,7 +3928,7 @@ void
gtk_widget_get_child_requisition (GtkWidget *widget,
GtkRequisition *requisition)
{
_gtk_size_group_get_child_requisition (widget, requisition);
gtk_extended_layout_get_desired_size (GTK_EXTENDED_LAYOUT (widget), requisition, NULL);
}
static gboolean
@@ -9282,9 +9282,6 @@ _gtk_widget_get_aux_info (GtkWidget *widget,
aux_info->width = -1;
aux_info->height = -1;
aux_info->cached_width_age = 1;
aux_info->cached_height_age = 1;
g_object_set_qdata (G_OBJECT (widget), quark_aux_info, aux_info);
}