diff options
author | Tristan Van Berkom <tristan.van.berkom@gmail.com> | 2010-10-12 17:16:32 +0900 |
---|---|---|
committer | Tristan Van Berkom <tristan.van.berkom@gmail.com> | 2010-10-12 17:16:32 +0900 |
commit | e85dad38e2c579598c142515c8b816ea6657e0c8 (patch) | |
tree | 13ba86bee3fcfca981813b290761ba2918661dda /gtk/gtkscrolledwindow.c | |
parent | 0e0d938cc3e3a841d2a3849f2b67048265b799b6 (diff) | |
download | gtk+-e85dad38e2c579598c142515c8b816ea6657e0c8.tar.gz |
Added logic to GtkScrolledWindow when allocating height-for-width children.
This patch makes the scrolled window reconsider allocating the child
the full width or height (depending on the child's request mode) without
a scrollbar. For instance when the child is height-for-width; the child
will first be tested if the content's height for full allocated width
(without a vscrollbar) will allow the contents height for that width
to fit the allocated height.
Patch is a simplified version of code inspected in st-scroll-view.c.
Note that this patch assumes children will begin to scroll only after
reaching their minimum size; adding a property to the future
GtkScrollableIface to decide whether to scroll-to-minimum or scroll-to-natural
will effect this code (it should then reconsider whether the child
will scroll below the natural size instead of the minimum).
Patch addresses bug 629778.
Diffstat (limited to 'gtk/gtkscrolledwindow.c')
-rw-r--r-- | gtk/gtkscrolledwindow.c | 124 |
1 files changed, 123 insertions, 1 deletions
diff --git a/gtk/gtkscrolledwindow.c b/gtk/gtkscrolledwindow.c index a6058b14ef..1a13b4aa53 100644 --- a/gtk/gtkscrolledwindow.c +++ b/gtk/gtkscrolledwindow.c @@ -1453,10 +1453,132 @@ gtk_scrolled_window_size_allocate (GtkWidget *widget, child = gtk_bin_get_child (bin); if (child && gtk_widget_get_visible (child)) { - gboolean previous_vvis; + gint child_min_width; + gint child_min_height; gboolean previous_hvis; + gboolean previous_vvis; guint count = 0; + /* In the case that both scrollbars are visible in the previous round, + * we dont do our guess-work before hand because it's possible some + * infinite recursion was detected (leave it up to the child scrollable + * widget in this case to drive the scrollbar visibility completely + * with the adjustment values). + */ + if (!priv->vscrollbar_visible || !priv->hscrollbar_visible) + { + + /* 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 (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 (priv->hscrollbar_policy == GTK_POLICY_AUTOMATIC) + { + /* Does the content height fit the allocation height ? */ + priv->vscrollbar_visible = child_min_height > allocation->height; + + /* Does the content width fit the allocation with minus a possible scrollbar ? */ + priv->hscrollbar_visible = + child_min_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 - + (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 - + (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->hscrollbar_visible ? sb_height + sb_spacing : 0); + } + } + else /* priv->vscrollbar_policy != GTK_POLICY_AUTOMATIC */ + { + priv->vscrollbar_visible = priv->vscrollbar_policy != GTK_POLICY_NEVER; + + if (priv->hscrollbar_policy == GTK_POLICY_AUTOMATIC) + priv->hscrollbar_visible = + child_min_width > allocation->width - + (priv->vscrollbar_visible ? 0 : sb_width + sb_spacing); + else + priv->hscrollbar_visible = priv->hscrollbar_policy != GTK_POLICY_NEVER; + } + } + else /* GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT */ + { + gtk_widget_get_preferred_height (child, &child_min_height, NULL); + + 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 (priv->vscrollbar_policy == GTK_POLICY_AUTOMATIC) + { + /* Does the content width fit the allocation width ? */ + priv->hscrollbar_visible = child_min_width > allocation->width; + + /* Does the content height fit the allocation with minus a possible scrollbar ? */ + priv->vscrollbar_visible = + child_min_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 - + (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 - + (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->vscrollbar_visible ? sb_width + sb_spacing : 0); + } + } + else /* priv->hscrollbar_policy != GTK_POLICY_AUTOMATIC */ + { + priv->hscrollbar_visible = priv->hscrollbar_policy != GTK_POLICY_NEVER; + + if (priv->vscrollbar_policy == GTK_POLICY_AUTOMATIC) + priv->vscrollbar_visible = + child_min_height > allocation->height - + (priv->hscrollbar_visible ? 0 : sb_height + sb_spacing); + else + priv->vscrollbar_visible = priv->vscrollbar_policy != GTK_POLICY_NEVER; + } + } + } + + /* Now after guessing scrollbar visibility; fall back on the allocation loop which + * observes the adjustments to detect scrollbar visibility and also avoids + * infinite recursion + */ do { gtk_scrolled_window_relative_allocation (widget, &relative_allocation); |