Added GtkScrollablePolicy property to scrollable interface
This patch adds the GtkScrollablePolicy type property to GtkScrollable and implements it in all subclasses. GtkScrolledWindow observes this property to make a good guess about when to show/hide scrollbars for height-for-width content. Most scrollable children do not do height-for-width *yet* but most certainly will (toolpalette, treeview, iconview, textview widgets all TODO), for scrollable widgets that do have a minimum and natural size, it's important for them to observe the state of this property in order to properly drive the scroll adjustments according to the desired GtkScrollablePolicy. This patch makes GtkViewport do this. Patch also adds tests/testscrolledwindow.c to display the effects of this property.
This commit is contained in:
@ -1460,8 +1460,6 @@ gtk_scrolled_window_size_allocate (GtkWidget *widget,
|
||||
gint sb_width;
|
||||
gint sb_height;
|
||||
|
||||
|
||||
|
||||
g_return_if_fail (GTK_IS_SCROLLED_WINDOW (widget));
|
||||
g_return_if_fail (allocation != NULL);
|
||||
|
||||
@ -1491,8 +1489,8 @@ gtk_scrolled_window_size_allocate (GtkWidget *widget,
|
||||
child = gtk_bin_get_child (bin);
|
||||
if (child && gtk_widget_get_visible (child))
|
||||
{
|
||||
gint child_min_width;
|
||||
gint child_min_height;
|
||||
gint child_scroll_width;
|
||||
gint child_scroll_height;
|
||||
gboolean previous_hvis;
|
||||
gboolean previous_vvis;
|
||||
guint count = 0;
|
||||
@ -1509,41 +1507,50 @@ gtk_scrolled_window_size_allocate (GtkWidget *widget,
|
||||
/* Determine scrollbar visibility first via hfw apis */
|
||||
if (gtk_widget_get_request_mode (child) == GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH)
|
||||
{
|
||||
gtk_widget_get_preferred_width (child, &child_min_width, NULL);
|
||||
|
||||
if (gtk_scrollable_get_hscroll_policy (GTK_SCROLLABLE (child)) == GTK_SCROLL_MINIMUM)
|
||||
gtk_widget_get_preferred_width (child, &child_scroll_width, NULL);
|
||||
else
|
||||
gtk_widget_get_preferred_width (child, NULL, &child_scroll_width);
|
||||
|
||||
if (priv->vscrollbar_policy == GTK_POLICY_AUTOMATIC)
|
||||
{
|
||||
/* First try without a vertical scrollbar if the content will fit the height
|
||||
* given the extra width of the scrollbar */
|
||||
gtk_widget_get_preferred_height_for_width (child, allocation->width,
|
||||
&child_min_height, NULL);
|
||||
|
||||
if (gtk_scrollable_get_vscroll_policy (GTK_SCROLLABLE (child)) == GTK_SCROLL_MINIMUM)
|
||||
gtk_widget_get_preferred_height_for_width (child,
|
||||
MAX (allocation->width, child_scroll_width),
|
||||
&child_scroll_height, NULL);
|
||||
else
|
||||
gtk_widget_get_preferred_height_for_width (child,
|
||||
MAX (allocation->width, child_scroll_width),
|
||||
NULL, &child_scroll_height);
|
||||
|
||||
if (priv->hscrollbar_policy == GTK_POLICY_AUTOMATIC)
|
||||
{
|
||||
/* Does the content height fit the allocation height ? */
|
||||
priv->vscrollbar_visible = child_min_height > allocation->height;
|
||||
priv->vscrollbar_visible = child_scroll_height > allocation->height;
|
||||
|
||||
/* Does the content width fit the allocation with minus a possible scrollbar ? */
|
||||
priv->hscrollbar_visible =
|
||||
child_min_width > allocation->width -
|
||||
child_scroll_width > allocation->width -
|
||||
(priv->vscrollbar_visible ? sb_width + sb_spacing : 0);
|
||||
|
||||
/* Now that we've guessed the hscrollbar, does the content height fit
|
||||
* the possible new allocation height ? */
|
||||
priv->vscrollbar_visible =
|
||||
child_min_height > allocation->height -
|
||||
child_scroll_height > allocation->height -
|
||||
(priv->hscrollbar_visible ? sb_height + sb_spacing : 0);
|
||||
|
||||
/* Now that we've guessed the vscrollbar, does the content width fit
|
||||
* the possible new allocation width ? */
|
||||
priv->hscrollbar_visible =
|
||||
child_min_width > allocation->width -
|
||||
child_scroll_width > allocation->width -
|
||||
(priv->vscrollbar_visible ? sb_width + sb_spacing : 0);
|
||||
}
|
||||
else /* priv->hscrollbar_policy != GTK_POLICY_AUTOMATIC */
|
||||
{
|
||||
priv->hscrollbar_visible = priv->hscrollbar_policy != GTK_POLICY_NEVER;
|
||||
priv->vscrollbar_visible = child_min_height > allocation->height -
|
||||
priv->vscrollbar_visible = child_scroll_height > allocation->height -
|
||||
(priv->hscrollbar_visible ? sb_height + sb_spacing : 0);
|
||||
}
|
||||
}
|
||||
@ -1553,7 +1560,7 @@ gtk_scrolled_window_size_allocate (GtkWidget *widget,
|
||||
|
||||
if (priv->hscrollbar_policy == GTK_POLICY_AUTOMATIC)
|
||||
priv->hscrollbar_visible =
|
||||
child_min_width > allocation->width -
|
||||
child_scroll_width > allocation->width -
|
||||
(priv->vscrollbar_visible ? 0 : sb_width + sb_spacing);
|
||||
else
|
||||
priv->hscrollbar_visible = priv->hscrollbar_policy != GTK_POLICY_NEVER;
|
||||
@ -1561,41 +1568,50 @@ gtk_scrolled_window_size_allocate (GtkWidget *widget,
|
||||
}
|
||||
else /* GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT */
|
||||
{
|
||||
gtk_widget_get_preferred_height (child, &child_min_height, NULL);
|
||||
|
||||
if (gtk_scrollable_get_vscroll_policy (GTK_SCROLLABLE (child)) == GTK_SCROLL_MINIMUM)
|
||||
gtk_widget_get_preferred_height (child, &child_scroll_height, NULL);
|
||||
else
|
||||
gtk_widget_get_preferred_height (child, NULL, &child_scroll_height);
|
||||
|
||||
if (priv->hscrollbar_policy == GTK_POLICY_AUTOMATIC)
|
||||
{
|
||||
/* First try without a horizontal scrollbar if the content will fit the width
|
||||
* given the extra height of the scrollbar */
|
||||
gtk_widget_get_preferred_width_for_height (child, allocation->height,
|
||||
&child_min_width, NULL);
|
||||
if (gtk_scrollable_get_hscroll_policy (GTK_SCROLLABLE (child)) == GTK_SCROLL_MINIMUM)
|
||||
gtk_widget_get_preferred_width_for_height (child,
|
||||
MAX (allocation->height, child_scroll_height),
|
||||
&child_scroll_width, NULL);
|
||||
else
|
||||
gtk_widget_get_preferred_width_for_height (child,
|
||||
MAX (allocation->height, child_scroll_height),
|
||||
NULL, &child_scroll_width);
|
||||
|
||||
if (priv->vscrollbar_policy == GTK_POLICY_AUTOMATIC)
|
||||
{
|
||||
/* Does the content width fit the allocation width ? */
|
||||
priv->hscrollbar_visible = child_min_width > allocation->width;
|
||||
priv->hscrollbar_visible = child_scroll_width > allocation->width;
|
||||
|
||||
/* Does the content height fit the allocation with minus a possible scrollbar ? */
|
||||
priv->vscrollbar_visible =
|
||||
child_min_height > allocation->height -
|
||||
child_scroll_height > allocation->height -
|
||||
(priv->hscrollbar_visible ? sb_height + sb_spacing : 0);
|
||||
|
||||
/* Now that we've guessed the vscrollbar, does the content width fit
|
||||
* the possible new allocation width ? */
|
||||
priv->hscrollbar_visible =
|
||||
child_min_width > allocation->width -
|
||||
child_scroll_width > allocation->width -
|
||||
(priv->vscrollbar_visible ? sb_width + sb_spacing : 0);
|
||||
|
||||
/* Now that we've guessed the hscrollbar, does the content height fit
|
||||
* the possible new allocation height ? */
|
||||
priv->vscrollbar_visible =
|
||||
child_min_height > allocation->height -
|
||||
child_scroll_height > allocation->height -
|
||||
(priv->hscrollbar_visible ? sb_height + sb_spacing : 0);
|
||||
}
|
||||
else /* priv->vscrollbar_policy != GTK_POLICY_AUTOMATIC */
|
||||
{
|
||||
priv->vscrollbar_visible = priv->vscrollbar_policy != GTK_POLICY_NEVER;
|
||||
priv->hscrollbar_visible = child_min_width > allocation->width -
|
||||
priv->hscrollbar_visible = child_scroll_width > allocation->width -
|
||||
(priv->vscrollbar_visible ? sb_width + sb_spacing : 0);
|
||||
}
|
||||
}
|
||||
@ -1605,7 +1621,7 @@ gtk_scrolled_window_size_allocate (GtkWidget *widget,
|
||||
|
||||
if (priv->vscrollbar_policy == GTK_POLICY_AUTOMATIC)
|
||||
priv->vscrollbar_visible =
|
||||
child_min_height > allocation->height -
|
||||
child_scroll_height > allocation->height -
|
||||
(priv->hscrollbar_visible ? 0 : sb_height + sb_spacing);
|
||||
else
|
||||
priv->vscrollbar_visible = priv->vscrollbar_policy != GTK_POLICY_NEVER;
|
||||
|
||||
Reference in New Issue
Block a user