* If a widget has native scrolling abilities, it can be added to the
* #GtkScrolledWindow with gtk_container_add(). If a widget does not, you
* must first add the widget to a #GtkViewport, then add the #GtkViewport
- * to the scrolled window. The convenience function
- * gtk_scrolled_window_add_with_viewport() does exactly this, so you can
+ * to the scrolled window. gtk_container_add() will do this for you for
+ * widgets that don't implement #GtkScrollable natively, so you can
* ignore the presence of the viewport.
*
* The position of the scrollbars is controlled by the scroll
static void gtk_scrolled_window_unrealize (GtkWidget *widget);
static void gtk_scrolled_window_map (GtkWidget *widget);
static void gtk_scrolled_window_unmap (GtkWidget *widget);
-static void gtk_scrolled_window_state_flags_changed (GtkWidget *widget,
- GtkStateFlags previous_state);
-static void gtk_scrolled_window_style_updated (GtkWidget *widget);
static void gtk_scrolled_window_grab_notify (GtkWidget *widget,
gboolean was_grabbed);
widget_class->unrealize = gtk_scrolled_window_unrealize;
widget_class->map = gtk_scrolled_window_map;
widget_class->unmap = gtk_scrolled_window_unmap;
- widget_class->state_flags_changed = gtk_scrolled_window_state_flags_changed;
- widget_class->style_updated = gtk_scrolled_window_style_updated;
widget_class->grab_notify = gtk_scrolled_window_grab_notify;
container_class->add = gtk_scrolled_window_add;
gtk_widget_get_preferred_height (priv->hscrollbar, &sb_height, NULL);
gtk_widget_get_preferred_width (priv->vscrollbar, &sb_width, NULL);
- /* Subtract some things from our available allocation size */
+ gtk_widget_get_allocation (widget, &widget_allocation);
+
allocation->x = 0;
allocation->y = 0;
+ allocation->width = widget_allocation.width;
+ allocation->height = widget_allocation.height;
+ /* Subtract some things from our available allocation size */
if (priv->shadow_type != GTK_SHADOW_NONE)
{
GtkStyleContext *context;
allocation->x += padding.left + border.left;
allocation->y += padding.top + border.top;
+ allocation->width = MAX (1, allocation->width - (padding.left + border.left + padding.right + border.right));
+ allocation->height = MAX (1, allocation->height - (padding.top + border.top + padding.bottom + border.bottom));
gtk_style_context_restore (context);
}
- gtk_widget_get_allocation (widget, &widget_allocation);
- allocation->width = MAX (1, (gint) widget_allocation.width - allocation->x * 2);
- allocation->height = MAX (1, (gint) widget_allocation.height - allocation->y * 2);
-
if (priv->vscrollbar_visible)
{
gboolean is_rtl;
{
gint child_scroll_width;
gint child_scroll_height;
+ GtkScrollablePolicy hscroll_policy;
+ GtkScrollablePolicy vscroll_policy;
gboolean previous_hvis;
gboolean previous_vvis;
guint count = 0;
+ hscroll_policy = GTK_IS_SCROLLABLE (child)
+ ? gtk_scrollable_get_hscroll_policy (GTK_SCROLLABLE (child))
+ : GTK_SCROLL_MINIMUM;
+ vscroll_policy = GTK_IS_SCROLLABLE (child)
+ ? gtk_scrollable_get_vscroll_policy (GTK_SCROLLABLE (child))
+ : GTK_SCROLL_MINIMUM;
+
/* Determine scrollbar visibility first via hfw apis */
if (gtk_widget_get_request_mode (child) == GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH)
{
- if (gtk_scrollable_get_hscroll_policy (GTK_SCROLLABLE (child)) == GTK_SCROLL_MINIMUM)
+ if (hscroll_policy == GTK_SCROLL_MINIMUM)
gtk_widget_get_preferred_width (child, &child_scroll_width, NULL);
else
gtk_widget_get_preferred_width (child, NULL, &child_scroll_width);
{
/* First try without a vertical scrollbar if the content will fit the height
* given the extra width of the scrollbar */
- if (gtk_scrollable_get_vscroll_policy (GTK_SCROLLABLE (child)) == GTK_SCROLL_MINIMUM)
+ if (vscroll_policy == GTK_SCROLL_MINIMUM)
gtk_widget_get_preferred_height_for_width (child,
MAX (allocation->width, child_scroll_width),
&child_scroll_height, NULL);
}
else /* GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT */
{
- if (gtk_scrollable_get_vscroll_policy (GTK_SCROLLABLE (child)) == GTK_SCROLL_MINIMUM)
+ if (vscroll_policy == GTK_SCROLL_MINIMUM)
gtk_widget_get_preferred_height (child, &child_scroll_height, NULL);
else
gtk_widget_get_preferred_height (child, NULL, &child_scroll_height);
{
/* First try without a horizontal scrollbar if the content will fit the width
* given the extra height of the scrollbar */
- if (gtk_scrollable_get_hscroll_policy (GTK_SCROLLABLE (child)) == GTK_SCROLL_MINIMUM)
+ if (hscroll_policy == GTK_SCROLL_MINIMUM)
gtk_widget_get_preferred_width_for_height (child,
MAX (allocation->height, child_scroll_height),
&child_scroll_width, NULL);
gtk_scrolled_window_relative_allocation (widget, &relative_allocation);
}
+ gtk_widget_set_child_visible (priv->hscrollbar, priv->hscrollbar_visible);
if (priv->hscrollbar_visible)
{
- if (!gtk_widget_get_visible (priv->hscrollbar))
- gtk_widget_show (priv->hscrollbar);
-
child_allocation.x = relative_allocation.x;
if (priv->real_window_placement == GTK_CORNER_TOP_LEFT ||
priv->real_window_placement == GTK_CORNER_TOP_RIGHT)
child_allocation.y = (relative_allocation.y +
relative_allocation.height +
- sb_spacing +
- (priv->shadow_type == GTK_SHADOW_NONE ?
- 0 : padding.top + border.top));
+ sb_spacing);
else
- child_allocation.y = 0;
+ child_allocation.y = relative_allocation.y - sb_spacing - sb_height;
child_allocation.width = relative_allocation.width;
child_allocation.height = sb_height;
{
child_allocation.x -= padding.left + border.left;
child_allocation.width += padding.left + padding.right + border.left + border.right;
- }
- else if (GTK_CORNER_TOP_RIGHT == priv->real_window_placement ||
- GTK_CORNER_TOP_LEFT == priv->real_window_placement)
- {
- child_allocation.y -= padding.top + border.top;
- }
- else
- {
- child_allocation.y += padding.top + border.top;
+
+ if (priv->real_window_placement == GTK_CORNER_TOP_LEFT ||
+ priv->real_window_placement == GTK_CORNER_TOP_RIGHT)
+ child_allocation.y += padding.bottom + border.bottom;
+ else
+ child_allocation.y -= padding.top + border.top;
}
}
gtk_widget_size_allocate (priv->hscrollbar, &child_allocation);
}
- else if (gtk_widget_get_visible (priv->hscrollbar))
- gtk_widget_hide (priv->hscrollbar);
+ gtk_widget_set_child_visible (priv->vscrollbar, priv->vscrollbar_visible);
if (priv->vscrollbar_visible)
{
- if (!gtk_widget_get_visible (priv->vscrollbar))
- gtk_widget_show (priv->vscrollbar);
-
if ((gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL &&
(priv->real_window_placement == GTK_CORNER_TOP_RIGHT ||
priv->real_window_placement == GTK_CORNER_BOTTOM_RIGHT)) ||
priv->real_window_placement == GTK_CORNER_BOTTOM_LEFT)))
child_allocation.x = (relative_allocation.x +
relative_allocation.width +
- sb_spacing +
- (priv->shadow_type == GTK_SHADOW_NONE ?
- 0 : padding.left + border.left));
+ sb_spacing);
else
- child_allocation.x = 0;
+ child_allocation.x = relative_allocation.x - sb_spacing - sb_width;
child_allocation.y = relative_allocation.y;
child_allocation.width = sb_width;
{
child_allocation.y -= padding.top + border.top;
child_allocation.height += padding.top + padding.bottom + border.top + border.bottom;
+
+ if ((gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL &&
+ (priv->real_window_placement == GTK_CORNER_TOP_RIGHT ||
+ priv->real_window_placement == GTK_CORNER_BOTTOM_RIGHT)) ||
+ (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR &&
+ (priv->real_window_placement == GTK_CORNER_TOP_LEFT ||
+ priv->real_window_placement == GTK_CORNER_BOTTOM_LEFT)))
+ child_allocation.x += padding.right + border.right;
+ else
+ child_allocation.x -= padding.left + border.left;
}
- else if (GTK_CORNER_BOTTOM_LEFT == priv->real_window_placement ||
- GTK_CORNER_TOP_LEFT == priv->real_window_placement)
- {
- child_allocation.x -= padding.left + border.left;
- }
- else
- {
- child_allocation.x += padding.left + border.left;
- }
- }
+ }
gtk_widget_size_allocate (priv->vscrollbar, &child_allocation);
}
- else if (gtk_widget_get_visible (priv->vscrollbar))
- gtk_widget_hide (priv->vscrollbar);
_gtk_scrolled_window_allocate_overshoot_window (scrolled_window);
}
GtkScrolledWindowPrivate *priv;
GtkScrolledWindow *scrolled_window;
GtkBin *bin;
- GtkWidget *child_widget;
+ GtkWidget *child_widget, *scrollable_child;
GtkAdjustment *hadj, *vadj;
bin = GTK_BIN (container);
scrolled_window = GTK_SCROLLED_WINDOW (container);
priv = scrolled_window->priv;
+ if (GTK_IS_SCROLLABLE (child))
+ {
+ scrollable_child = child;
+ }
+ else
+ {
+ scrollable_child = gtk_viewport_new (NULL, NULL);
+ gtk_widget_show (scrollable_child);
+ gtk_container_add (GTK_CONTAINER (scrollable_child), child);
+ }
+
if (gtk_widget_get_realized (GTK_WIDGET (bin)))
- gtk_widget_set_parent_window (child, priv->overshoot_window);
+ gtk_widget_set_parent_window (scrollable_child, priv->overshoot_window);
- _gtk_bin_set_child (bin, child);
- gtk_widget_set_parent (child, GTK_WIDGET (bin));
+ _gtk_bin_set_child (bin, scrollable_child);
+ gtk_widget_set_parent (scrollable_child, GTK_WIDGET (bin));
hadj = gtk_range_get_adjustment (GTK_RANGE (priv->hscrollbar));
vadj = gtk_range_get_adjustment (GTK_RANGE (priv->vscrollbar));
- if (GTK_IS_SCROLLABLE (child))
- g_object_set (child, "hadjustment", hadj, "vadjustment", vadj, NULL);
- else
- g_warning ("gtk_scrolled_window_add(): cannot add non scrollable widget "
- "use gtk_scrolled_window_add_with_viewport() instead");
+ g_object_set (scrollable_child, "hadjustment", hadj, "vadjustment", vadj, NULL);
}
static void
*
* A widget supports scrolling natively if it implements the
* #GtkScrollable interface.
+ *
+ * Deprecated: 3.8: gtk_container_add() will now automatically add
+ * a #GtkViewport if the child doesn't implement #GtkScrollable.
*/
void
gtk_scrolled_window_add_with_viewport (GtkScrolledWindow *scrolled_window,
attributes.wclass = GDK_INPUT_OUTPUT;
attributes.visual = gtk_widget_get_visual (widget);
attributes.event_mask = GDK_VISIBILITY_NOTIFY_MASK |
- GDK_BUTTON_MOTION_MASK | GDK_TOUCH_MASK;
+ GDK_BUTTON_MOTION_MASK | GDK_TOUCH_MASK | GDK_EXPOSURE_MASK;
attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL;
scrolled_window->priv->overshoot_window =
gdk_window_new (gtk_widget_get_parent_window (widget),
&attributes, attributes_mask);
-
- gdk_window_set_user_data (scrolled_window->priv->overshoot_window, widget);
+ gtk_widget_register_window (widget, scrolled_window->priv->overshoot_window);
child_widget = gtk_bin_get_child (GTK_BIN (widget));
{
GtkScrolledWindow *scrolled_window = GTK_SCROLLED_WINDOW (widget);
- gdk_window_set_user_data (scrolled_window->priv->overshoot_window, NULL);
+ gtk_widget_unregister_window (widget, scrolled_window->priv->overshoot_window);
gdk_window_destroy (scrolled_window->priv->overshoot_window);
scrolled_window->priv->overshoot_window = NULL;
GTK_WIDGET_CLASS (gtk_scrolled_window_parent_class)->unmap (widget);
}
-static void
-_gtk_scrolled_window_update_background (GtkScrolledWindow *scrolled_window)
-{
- GtkWidget *widget = GTK_WIDGET (scrolled_window);
-
- if (gtk_widget_get_realized (widget))
- {
- GtkStyleContext *context;
-
- context = gtk_widget_get_style_context (widget);
- gtk_style_context_set_background (context, scrolled_window->priv->overshoot_window);
- }
-}
-
-static void
-gtk_scrolled_window_state_flags_changed (GtkWidget *widget,
- GtkStateFlags previous_state)
-{
- _gtk_scrolled_window_update_background (GTK_SCROLLED_WINDOW (widget));
- gtk_widget_queue_draw (widget);
-}
-
-static void
-gtk_scrolled_window_style_updated (GtkWidget *widget)
-{
- GTK_WIDGET_CLASS (gtk_scrolled_window_parent_class)->style_updated (widget);
-
- _gtk_scrolled_window_update_background (GTK_SCROLLED_WINDOW (widget));
- gtk_widget_queue_draw (widget);
-}
-
static void
gtk_scrolled_window_grab_notify (GtkWidget *widget,
gboolean was_grabbed)