forked from AuroraMiddleware/gtk
Added GTK_SIZE_REQUEST_CONSTANT_SIZE to GtkSizeRequestMode
The constant size request mode defines a request mode where height-for-width geometry is unneeded, thus optimizing GTK+ by reducing the overall amount of requests that need to be performed and cached while resizing an interface.
This commit is contained in:
parent
59440927d0
commit
887142f1f5
14
gtk/gtkbin.c
14
gtk/gtkbin.c
@ -59,7 +59,6 @@ static void gtk_bin_forall (GtkContainer *container,
|
||||
static GType gtk_bin_child_type (GtkContainer *container);
|
||||
|
||||
|
||||
static GtkSizeRequestMode gtk_bin_get_request_mode (GtkWidget *widget);
|
||||
static void gtk_bin_get_preferred_width_for_height (GtkWidget *widget,
|
||||
gint height,
|
||||
gint *minimum_width,
|
||||
@ -77,7 +76,6 @@ gtk_bin_class_init (GtkBinClass *class)
|
||||
GtkWidgetClass *widget_class = (GtkWidgetClass*) class;
|
||||
GtkContainerClass *container_class = (GtkContainerClass*) class;
|
||||
|
||||
widget_class->get_request_mode = gtk_bin_get_request_mode;
|
||||
widget_class->get_preferred_width_for_height = gtk_bin_get_preferred_width_for_height;
|
||||
widget_class->get_preferred_height_for_width = gtk_bin_get_preferred_height_for_width;
|
||||
|
||||
@ -184,18 +182,6 @@ gtk_bin_forall (GtkContainer *container,
|
||||
* deduce a common code path for the get_width_for_height()/get_height_for_width()
|
||||
* cases by using the delta of the base size requsts.
|
||||
*/
|
||||
static GtkSizeRequestMode
|
||||
gtk_bin_get_request_mode (GtkWidget *widget)
|
||||
{
|
||||
GtkBin *bin = GTK_BIN (widget);
|
||||
GtkBinPrivate *priv = bin->priv;
|
||||
|
||||
if (priv->child)
|
||||
return gtk_widget_get_request_mode (priv->child);
|
||||
|
||||
return GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH;
|
||||
}
|
||||
|
||||
static void
|
||||
get_child_padding_delta (GtkBin *bin,
|
||||
gint *delta_h,
|
||||
|
12
gtk/gtkbox.c
12
gtk/gtkbox.c
@ -185,7 +185,6 @@ static void gtk_box_get_child_property (GtkContainer *container,
|
||||
static GType gtk_box_child_type (GtkContainer *container);
|
||||
|
||||
|
||||
static GtkSizeRequestMode gtk_box_get_request_mode (GtkWidget *widget);
|
||||
static void gtk_box_get_preferred_width (GtkWidget *widget,
|
||||
gint *minimum_size,
|
||||
gint *natural_size);
|
||||
@ -216,7 +215,6 @@ gtk_box_class_init (GtkBoxClass *class)
|
||||
object_class->get_property = gtk_box_get_property;
|
||||
|
||||
widget_class->size_allocate = gtk_box_size_allocate;
|
||||
widget_class->get_request_mode = gtk_box_get_request_mode;
|
||||
widget_class->get_preferred_width = gtk_box_get_preferred_width;
|
||||
widget_class->get_preferred_height = gtk_box_get_preferred_height;
|
||||
widget_class->get_preferred_height_for_width = gtk_box_get_preferred_height_for_width;
|
||||
@ -870,16 +868,6 @@ gtk_box_pack (GtkBox *box,
|
||||
gtk_widget_thaw_child_notify (child);
|
||||
}
|
||||
|
||||
|
||||
static GtkSizeRequestMode
|
||||
gtk_box_get_request_mode (GtkWidget *widget)
|
||||
{
|
||||
GtkBoxPrivate *private = GTK_BOX (widget)->priv;
|
||||
|
||||
return (private->orientation == GTK_ORIENTATION_VERTICAL) ?
|
||||
GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH : GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_box_get_size (GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
|
@ -93,6 +93,7 @@ static void gtk_cell_view_buildable_custom_tag_end (GtkBuildable
|
||||
const gchar *tagname,
|
||||
gpointer *data);
|
||||
|
||||
static GtkSizeRequestMode gtk_cell_view_get_request_mode (GtkWidget *widget);
|
||||
static void gtk_cell_view_get_preferred_width (GtkWidget *widget,
|
||||
gint *minimum_size,
|
||||
gint *natural_size);
|
||||
@ -175,6 +176,7 @@ gtk_cell_view_class_init (GtkCellViewClass *klass)
|
||||
|
||||
widget_class->draw = gtk_cell_view_draw;
|
||||
widget_class->size_allocate = gtk_cell_view_size_allocate;
|
||||
widget_class->get_request_mode = gtk_cell_view_get_request_mode;
|
||||
widget_class->get_preferred_width = gtk_cell_view_get_preferred_width;
|
||||
widget_class->get_preferred_height = gtk_cell_view_get_preferred_height;
|
||||
widget_class->get_preferred_width_for_height = gtk_cell_view_get_preferred_width_for_height;
|
||||
@ -637,6 +639,15 @@ gtk_cell_view_request_model (GtkCellView *cellview,
|
||||
}
|
||||
}
|
||||
|
||||
static GtkSizeRequestMode
|
||||
gtk_cell_view_get_request_mode (GtkWidget *widget)
|
||||
{
|
||||
GtkCellView *cellview = GTK_CELL_VIEW (widget);
|
||||
GtkCellViewPrivate *priv = cellview->priv;
|
||||
|
||||
return gtk_cell_area_get_request_mode (priv->area);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_cell_view_get_preferred_width (GtkWidget *widget,
|
||||
gint *minimum_size,
|
||||
|
@ -239,6 +239,7 @@ struct _GtkContainerPrivate
|
||||
guint need_resize : 1;
|
||||
guint reallocate_redraws : 1;
|
||||
guint resize_mode : 2;
|
||||
guint request_mode : 2;
|
||||
};
|
||||
|
||||
enum {
|
||||
@ -307,6 +308,7 @@ static void gtk_container_adjust_size_allocation (GtkWidget *widget,
|
||||
gint *natural_size,
|
||||
gint *allocated_pos,
|
||||
gint *allocated_size);
|
||||
static GtkSizeRequestMode gtk_container_get_request_mode (GtkWidget *widget);
|
||||
|
||||
static gchar* gtk_container_child_default_composite_name (GtkContainer *container,
|
||||
GtkWidget *child);
|
||||
@ -437,6 +439,7 @@ gtk_container_class_init (GtkContainerClass *class)
|
||||
|
||||
widget_class->adjust_size_request = gtk_container_adjust_size_request;
|
||||
widget_class->adjust_size_allocation = gtk_container_adjust_size_allocation;
|
||||
widget_class->get_request_mode = gtk_container_get_request_mode;
|
||||
|
||||
class->add = gtk_container_add_unimplemented;
|
||||
class->remove = gtk_container_remove_unimplemented;
|
||||
@ -1851,6 +1854,57 @@ gtk_container_adjust_size_allocation (GtkWidget *widget,
|
||||
allocated_size);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
gint hfw;
|
||||
gint wfh;
|
||||
} RequestModeCount;
|
||||
|
||||
static void
|
||||
count_request_modes (GtkWidget *widget,
|
||||
RequestModeCount *count)
|
||||
{
|
||||
GtkSizeRequestMode mode = gtk_widget_get_request_mode (widget);
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH:
|
||||
count->hfw++;
|
||||
break;
|
||||
case GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT:
|
||||
count->wfh++;
|
||||
break;
|
||||
case GTK_SIZE_REQUEST_CONSTANT_SIZE:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static GtkSizeRequestMode
|
||||
gtk_container_get_request_mode (GtkWidget *widget)
|
||||
{
|
||||
GtkContainer *container = GTK_CONTAINER (widget);
|
||||
GtkContainerPrivate *priv = container->priv;
|
||||
|
||||
/* Recalculate the request mode of the children by majority
|
||||
* vote whenever the internal content changes */
|
||||
if (_gtk_widget_get_width_request_needed (widget) ||
|
||||
_gtk_widget_get_height_request_needed (widget))
|
||||
{
|
||||
RequestModeCount count = { 0, 0 };
|
||||
|
||||
gtk_container_forall (container, (GtkCallback)count_request_modes, &count);
|
||||
|
||||
if (!count.hfw && !count.wfh)
|
||||
priv->request_mode = GTK_SIZE_REQUEST_CONSTANT_SIZE;
|
||||
else
|
||||
priv->request_mode = count.wfh > count.hfw ?
|
||||
GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT :
|
||||
GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH;
|
||||
}
|
||||
|
||||
return priv->request_mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_container_class_handle_border_width:
|
||||
* @klass: the class struct of a #GtkContainer subclass
|
||||
|
@ -790,6 +790,7 @@ typedef enum
|
||||
* GtkSizeRequestMode:
|
||||
* @GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH: Prefer height-for-width geometry management
|
||||
* @GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT: Prefer width-for-height geometry management
|
||||
* @GTK_SIZE_REQUEST_CONSTANT_SIZE: Dont trade height-for-width or width-for-height
|
||||
*
|
||||
* Specifies a preference for height-for-width or
|
||||
* width-for-height geometry management.
|
||||
@ -797,7 +798,8 @@ typedef enum
|
||||
typedef enum
|
||||
{
|
||||
GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH = 0,
|
||||
GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT
|
||||
GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT,
|
||||
GTK_SIZE_REQUEST_CONSTANT_SIZE
|
||||
} GtkSizeRequestMode;
|
||||
|
||||
/**
|
||||
|
@ -458,17 +458,6 @@ gtk_grid_child_type (GtkContainer *container)
|
||||
return GTK_TYPE_WIDGET;
|
||||
}
|
||||
|
||||
static GtkSizeRequestMode
|
||||
gtk_grid_get_request_mode (GtkWidget *widget)
|
||||
{
|
||||
GtkGridPrivate *priv = GTK_GRID (widget)->priv;
|
||||
|
||||
if (priv->orientation == GTK_ORIENTATION_VERTICAL)
|
||||
return GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH;
|
||||
else
|
||||
return GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT;
|
||||
}
|
||||
|
||||
/* Calculates the min and max numbers for both orientations.
|
||||
*/
|
||||
static void
|
||||
@ -1104,8 +1093,7 @@ gtk_grid_get_preferred_width (GtkWidget *widget,
|
||||
{
|
||||
GtkGrid *grid = GTK_GRID (widget);
|
||||
|
||||
if (gtk_grid_get_request_mode (widget) == GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT)
|
||||
|
||||
if (gtk_widget_get_request_mode (widget) == GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT)
|
||||
gtk_grid_get_size_for_size (grid, GTK_ORIENTATION_HORIZONTAL, 0, minimum, natural);
|
||||
else
|
||||
gtk_grid_get_size (grid, GTK_ORIENTATION_HORIZONTAL, minimum, natural);
|
||||
@ -1118,7 +1106,7 @@ gtk_grid_get_preferred_height (GtkWidget *widget,
|
||||
{
|
||||
GtkGrid *grid = GTK_GRID (widget);
|
||||
|
||||
if (gtk_grid_get_request_mode (widget) == GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH)
|
||||
if (gtk_widget_get_request_mode (widget) == GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH)
|
||||
gtk_grid_get_size_for_size (grid, GTK_ORIENTATION_VERTICAL, 0, minimum, natural);
|
||||
else
|
||||
gtk_grid_get_size (grid, GTK_ORIENTATION_VERTICAL, minimum, natural);
|
||||
@ -1132,7 +1120,7 @@ gtk_grid_get_preferred_width_for_height (GtkWidget *widget,
|
||||
{
|
||||
GtkGrid *grid = GTK_GRID (widget);
|
||||
|
||||
if (gtk_grid_get_request_mode (widget) == GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT)
|
||||
if (gtk_widget_get_request_mode (widget) == GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT)
|
||||
gtk_grid_get_size_for_size (grid, GTK_ORIENTATION_HORIZONTAL, height, minimum, natural);
|
||||
else
|
||||
gtk_grid_get_size (grid, GTK_ORIENTATION_HORIZONTAL, minimum, natural);
|
||||
@ -1146,7 +1134,7 @@ gtk_grid_get_preferred_height_for_width (GtkWidget *widget,
|
||||
{
|
||||
GtkGrid *grid = GTK_GRID (widget);
|
||||
|
||||
if (gtk_grid_get_request_mode (widget) == GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH)
|
||||
if (gtk_widget_get_request_mode (widget) == GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH)
|
||||
gtk_grid_get_size_for_size (grid, GTK_ORIENTATION_VERTICAL, width, minimum, natural);
|
||||
else
|
||||
gtk_grid_get_size (grid, GTK_ORIENTATION_VERTICAL, minimum, natural);
|
||||
@ -1258,7 +1246,6 @@ gtk_grid_class_init (GtkGridClass *class)
|
||||
widget_class->size_allocate = gtk_grid_size_allocate;
|
||||
widget_class->get_preferred_width = gtk_grid_get_preferred_width;
|
||||
widget_class->get_preferred_height = gtk_grid_get_preferred_height;
|
||||
widget_class->get_request_mode = gtk_grid_get_request_mode;
|
||||
widget_class->get_preferred_width_for_height = gtk_grid_get_preferred_width_for_height;
|
||||
widget_class->get_preferred_height_for_width = gtk_grid_get_preferred_height_for_width;
|
||||
|
||||
|
@ -3381,10 +3381,12 @@ gtk_label_get_request_mode (GtkWidget *widget)
|
||||
GtkLabel *label = GTK_LABEL (widget);
|
||||
gdouble angle = gtk_label_get_angle (label);
|
||||
|
||||
if (angle == 90 || angle == 270)
|
||||
return GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT;
|
||||
if (label->priv->wrap)
|
||||
return (angle == 90 || angle == 270) ?
|
||||
GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT :
|
||||
GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH;
|
||||
|
||||
return GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH;
|
||||
return GTK_SIZE_REQUEST_CONSTANT_SIZE;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -156,6 +156,11 @@ pop_recursion_check (GtkWidget *widget,
|
||||
#endif
|
||||
}
|
||||
|
||||
/* This is the main function that checks for a cached size and
|
||||
* possibly queries the widget class to compute the size if it's
|
||||
* not cached. If the for_size here is -1, then get_preferred_width()
|
||||
* or get_preferred_height() will be used.
|
||||
*/
|
||||
static void
|
||||
compute_size_for_orientation (GtkWidget *widget,
|
||||
GtkSizeGroupMode orientation,
|
||||
@ -168,9 +173,6 @@ compute_size_for_orientation (GtkWidget *widget,
|
||||
gboolean found_in_cache = FALSE;
|
||||
int adjusted_min, adjusted_natural;
|
||||
|
||||
g_return_if_fail (GTK_IS_WIDGET (widget));
|
||||
g_return_if_fail (minimum_size != NULL || natural_size != NULL);
|
||||
|
||||
cache = _gtk_widget_peek_request_cache (widget);
|
||||
|
||||
if (orientation == GTK_SIZE_GROUP_HORIZONTAL)
|
||||
@ -399,6 +401,9 @@ gtk_widget_get_preferred_width (GtkWidget *widget,
|
||||
gint *minimum_width,
|
||||
gint *natural_width)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_WIDGET (widget));
|
||||
g_return_if_fail (minimum_width != NULL || natural_width != NULL);
|
||||
|
||||
compute_size_for_orientation (widget, GTK_SIZE_GROUP_HORIZONTAL,
|
||||
-1, minimum_width, natural_width);
|
||||
}
|
||||
@ -427,6 +432,9 @@ gtk_widget_get_preferred_height (GtkWidget *widget,
|
||||
gint *minimum_height,
|
||||
gint *natural_height)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_WIDGET (widget));
|
||||
g_return_if_fail (minimum_height != NULL || natural_height != NULL);
|
||||
|
||||
compute_size_for_orientation (widget, GTK_SIZE_GROUP_VERTICAL,
|
||||
-1, minimum_height, natural_height);
|
||||
}
|
||||
@ -457,8 +465,16 @@ gtk_widget_get_preferred_width_for_height (GtkWidget *widget,
|
||||
gint *minimum_width,
|
||||
gint *natural_width)
|
||||
{
|
||||
compute_size_for_orientation (widget, GTK_SIZE_GROUP_HORIZONTAL,
|
||||
height, minimum_width, natural_width);
|
||||
g_return_if_fail (GTK_IS_WIDGET (widget));
|
||||
g_return_if_fail (minimum_width != NULL || natural_width != NULL);
|
||||
g_return_if_fail (height >= 0);
|
||||
|
||||
if (GTK_WIDGET_GET_CLASS (widget)->get_request_mode (widget) == GTK_SIZE_REQUEST_CONSTANT_SIZE)
|
||||
compute_size_for_orientation (widget, GTK_SIZE_GROUP_HORIZONTAL,
|
||||
-1, minimum_width, natural_width);
|
||||
else
|
||||
compute_size_for_orientation (widget, GTK_SIZE_GROUP_HORIZONTAL,
|
||||
height, minimum_width, natural_width);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -485,8 +501,16 @@ gtk_widget_get_preferred_height_for_width (GtkWidget *widget,
|
||||
gint *minimum_height,
|
||||
gint *natural_height)
|
||||
{
|
||||
compute_size_for_orientation (widget, GTK_SIZE_GROUP_VERTICAL,
|
||||
width, minimum_height, natural_height);
|
||||
g_return_if_fail (GTK_IS_WIDGET (widget));
|
||||
g_return_if_fail (minimum_height != NULL || natural_height != NULL);
|
||||
g_return_if_fail (width >= 0);
|
||||
|
||||
if (GTK_WIDGET_GET_CLASS (widget)->get_request_mode (widget) == GTK_SIZE_REQUEST_CONSTANT_SIZE)
|
||||
compute_size_for_orientation (widget, GTK_SIZE_GROUP_VERTICAL,
|
||||
-1, minimum_height, natural_height);
|
||||
else
|
||||
compute_size_for_orientation (widget, GTK_SIZE_GROUP_VERTICAL,
|
||||
width, minimum_height, natural_height);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -538,7 +562,7 @@ gtk_widget_get_preferred_size (GtkWidget *widget,
|
||||
NULL, &natural_size->height);
|
||||
}
|
||||
}
|
||||
else /* GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT */
|
||||
else /* GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT or CONSTANT_SIZE */
|
||||
{
|
||||
gtk_widget_get_preferred_height (widget, &min_height, &nat_height);
|
||||
|
||||
|
@ -13007,8 +13007,8 @@ gtk_widget_buildable_custom_finished (GtkBuildable *buildable,
|
||||
static GtkSizeRequestMode
|
||||
gtk_widget_real_get_request_mode (GtkWidget *widget)
|
||||
{
|
||||
/* By default widgets are height-for-width. */
|
||||
return GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH;
|
||||
/* By default widgets dont trade size at all. */
|
||||
return GTK_SIZE_REQUEST_CONSTANT_SIZE;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -139,12 +139,15 @@ struct _GtkWidget
|
||||
* %GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT mode.
|
||||
* %GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH means the widget prefers to have
|
||||
* #GtkWidgetClass.get_preferred_width() called and then
|
||||
* #GtkWidgetClass.get_preferred_height_for_width() and is the default
|
||||
* return for unimplemented cases.
|
||||
* However it's important to note (as described below) that any widget
|
||||
* which trades height-for-width must respond properly to both
|
||||
* #GtkSizeRequestModes since it might be queried in either orientation
|
||||
* by its parent container.
|
||||
* #GtkWidgetClass.get_preferred_height_for_width().
|
||||
* %GTK_SIZE_REQUEST_CONSTANT_SIZE disables any height-for-width or
|
||||
* width-for-height geometry management for a said widget and is the
|
||||
* default return.
|
||||
* It's important to note (as described below) that any widget
|
||||
* which trades height-for-width or width-for-height must respond properly
|
||||
* to both of the virtual methods #GtkWidgetClass.get_preferred_height_for_width()
|
||||
* and #GtkWidgetClass.get_preferred_width_for_height() since it might be
|
||||
* queried in either #GtkSizeRequestMode by its parent container.
|
||||
* @get_preferred_height: This is called by containers to obtain the minimum
|
||||
* and natural height of a widget. A widget that does not actually trade
|
||||
* any height for width or width for height only has to implement these
|
||||
|
Loading…
Reference in New Issue
Block a user