* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* GtkLayout: Widget for scrolling of arbitrary-sized areas.
*
#include "config.h"
-#undef GTK_DISABLE_DEPRECATED
-
#include "gtklayout.h"
-#include "gdkconfig.h"
+#include "gdk/gdk.h"
-#include "gtkprivate.h"
+#include "gtkadjustment.h"
#include "gtkintl.h"
#include "gtkmarshalers.h"
+#include "gtkprivate.h"
#include "gtkscrollable.h"
+/**
+ * SECTION:gtklayout
+ * @Short_description: Infinite scrollable area containing child widgets
+ * and/or custom drawing
+ * @Title: GtkLayout
+ * @See_also: #GtkDrawingArea, #GtkScrolledWindow
+ *
+ * #GtkLayout is similar to #GtkDrawingArea in that it's a "blank slate"
+ * and doesn't do anything but paint a blank background by default. It's
+ * different in that it supports scrolling natively (you can add it to a
+ * #GtkScrolledWindow), and it can contain child widgets, since it's a
+ * #GtkContainer. However if you're just going to draw, a #GtkDrawingArea
+ * is a better choice since it has lower overhead.
+ *
+ * When handling expose events on a #GtkLayout, you must draw to
+ * GTK_LAYOUT (layout)->bin_window, rather than to
+ * GTK_WIDGET (layout)->window, as you would for a drawing
+ * area.
+ */
+
+
typedef struct _GtkLayoutChild GtkLayoutChild;
struct _GtkLayoutPrivate
GtkAdjustment *hadjustment;
GtkAdjustment *vadjustment;
+ /* GtkScrollablePolicy needs to be checked when
+ * driving the scrollable adjustment values */
+ guint hscroll_policy : 1;
+ guint vscroll_policy : 1;
+
/* Properties */
GdkVisibilityState visibility;
PROP_0,
PROP_HADJUSTMENT,
PROP_VADJUSTMENT,
+ PROP_HSCROLL_POLICY,
+ PROP_VSCROLL_POLICY,
PROP_WIDTH,
PROP_HEIGHT
};
static void gtk_layout_realize (GtkWidget *widget);
static void gtk_layout_unrealize (GtkWidget *widget);
static void gtk_layout_map (GtkWidget *widget);
-static void gtk_layout_size_request (GtkWidget *widget,
- GtkRequisition *requisition);
+static void gtk_layout_get_preferred_width (GtkWidget *widget,
+ gint *minimum,
+ gint *natural);
+static void gtk_layout_get_preferred_height (GtkWidget *widget,
+ gint *minimum,
+ gint *natural);
static void gtk_layout_size_allocate (GtkWidget *widget,
GtkAllocation *allocation);
static gint gtk_layout_draw (GtkWidget *widget,
GtkLayoutChild *child);
static void gtk_layout_adjustment_changed (GtkAdjustment *adjustment,
GtkLayout *layout);
-static void gtk_layout_style_set (GtkWidget *widget,
- GtkStyle *old_style);
+static void gtk_layout_style_updated (GtkWidget *widget);
static void gtk_layout_set_hadjustment_values (GtkLayout *layout);
static void gtk_layout_set_vadjustment_values (GtkLayout *layout);
G_OBJECT_CLASS (gtk_layout_parent_class)->finalize (object);
}
-/**
- * gtk_layout_set_hadjustment:
- * @layout: a #GtkLayout
- * @adjustment: (allow-none): new scroll adjustment
- *
- * Sets the horizontal scroll adjustment for the layout.
- *
- * See #GtkScrolledWindow, #GtkScrollbar, #GtkAdjustment for details.
- *
- * Deprecated: 3.0: Use gtk_scrollable_set_hadjustment()
- **/
-void
-gtk_layout_set_hadjustment (GtkLayout *layout,
- GtkAdjustment *adjustment)
+static void
+gtk_layout_do_set_hadjustment (GtkLayout *layout,
+ GtkAdjustment *adjustment)
{
GtkLayoutPrivate *priv;
- g_return_if_fail (GTK_IS_LAYOUT (layout));
- g_return_if_fail (adjustment == NULL || GTK_IS_ADJUSTMENT (adjustment));
-
priv = layout->priv;
if (adjustment && priv->hadjustment == adjustment)
g_object_notify (G_OBJECT (layout), "hadjustment");
}
-
/**
- * gtk_layout_set_vadjustment:
+ * gtk_layout_set_hadjustment:
* @layout: a #GtkLayout
* @adjustment: (allow-none): new scroll adjustment
*
- * Sets the vertical scroll adjustment for the layout.
+ * Sets the horizontal scroll adjustment for the layout.
*
* See #GtkScrolledWindow, #GtkScrollbar, #GtkAdjustment for details.
*
- * Deprecated: 3.0: Use gtk_scrollable_set_vadjustment()
+ * Deprecated: 3.0: Use gtk_scrollable_set_hadjustment()
**/
void
-gtk_layout_set_vadjustment (GtkLayout *layout,
+gtk_layout_set_hadjustment (GtkLayout *layout,
GtkAdjustment *adjustment)
{
- GtkLayoutPrivate *priv;
-
g_return_if_fail (GTK_IS_LAYOUT (layout));
g_return_if_fail (adjustment == NULL || GTK_IS_ADJUSTMENT (adjustment));
+ gtk_layout_do_set_hadjustment (layout, adjustment);
+}
+
+static void
+gtk_layout_do_set_vadjustment (GtkLayout *layout,
+ GtkAdjustment *adjustment)
+{
+ GtkLayoutPrivate *priv;
+
priv = layout->priv;
if (adjustment && priv->vadjustment == adjustment)
g_object_notify (G_OBJECT (layout), "vadjustment");
}
+/**
+ * gtk_layout_set_vadjustment:
+ * @layout: a #GtkLayout
+ * @adjustment: (allow-none): new scroll adjustment
+ *
+ * Sets the vertical scroll adjustment for the layout.
+ *
+ * See #GtkScrolledWindow, #GtkScrollbar, #GtkAdjustment for details.
+ *
+ * Deprecated: 3.0: Use gtk_scrollable_set_vadjustment()
+ **/
+void
+gtk_layout_set_vadjustment (GtkLayout *layout,
+ GtkAdjustment *adjustment)
+{
+ g_return_if_fail (GTK_IS_LAYOUT (layout));
+ g_return_if_fail (adjustment == NULL || GTK_IS_ADJUSTMENT (adjustment));
+
+ gtk_layout_do_set_vadjustment (layout, adjustment);
+}
+
static GtkLayoutChild*
get_child (GtkLayout *layout,
GtkWidget *widget)
/**
* gtk_layout_get_size:
* @layout: a #GtkLayout
- * @width: (allow-none): location to store the width set on @layout, or %NULL
- * @height: (allow-none): location to store the height set on @layout, or %NULL
+ * @width: (out) (allow-none): location to store the width set on
+ * @layout, or %NULL
+ * @height: (out) (allow-none): location to store the height set on
+ * @layout, or %NULL
*
* Gets the size that has been set on the layout, and that determines
* the total extents of the layout's scrollbar area. See
GTK_PARAM_READWRITE));
/* Scrollable interface */
- g_object_class_override_property (gobject_class, PROP_HADJUSTMENT, "hadjustment");
- g_object_class_override_property (gobject_class, PROP_VADJUSTMENT, "vadjustment");
+ g_object_class_override_property (gobject_class, PROP_HADJUSTMENT, "hadjustment");
+ g_object_class_override_property (gobject_class, PROP_VADJUSTMENT, "vadjustment");
+ g_object_class_override_property (gobject_class, PROP_HSCROLL_POLICY, "hscroll-policy");
+ g_object_class_override_property (gobject_class, PROP_VSCROLL_POLICY, "vscroll-policy");
g_object_class_install_property (gobject_class,
PROP_WIDTH,
widget_class->realize = gtk_layout_realize;
widget_class->unrealize = gtk_layout_unrealize;
widget_class->map = gtk_layout_map;
- widget_class->size_request = gtk_layout_size_request;
+ widget_class->get_preferred_width = gtk_layout_get_preferred_width;
+ widget_class->get_preferred_height = gtk_layout_get_preferred_height;
widget_class->size_allocate = gtk_layout_size_allocate;
widget_class->draw = gtk_layout_draw;
- widget_class->style_set = gtk_layout_style_set;
+ widget_class->style_updated = gtk_layout_style_updated;
container_class->add = gtk_layout_add;
container_class->remove = gtk_layout_remove;
case PROP_VADJUSTMENT:
g_value_set_object (value, priv->vadjustment);
break;
+ case PROP_HSCROLL_POLICY:
+ g_value_set_enum (value, priv->hscroll_policy);
+ break;
+ case PROP_VSCROLL_POLICY:
+ g_value_set_enum (value, priv->vscroll_policy);
+ break;
case PROP_WIDTH:
g_value_set_uint (value, priv->width);
break;
switch (prop_id)
{
case PROP_HADJUSTMENT:
- gtk_layout_set_hadjustment (layout,
- (GtkAdjustment*) g_value_get_object (value));
+ gtk_layout_do_set_hadjustment (layout, g_value_get_object (value));
break;
case PROP_VADJUSTMENT:
- gtk_layout_set_vadjustment (layout,
- (GtkAdjustment*) g_value_get_object (value));
+ gtk_layout_do_set_vadjustment (layout, g_value_get_object (value));
+ break;
+ case PROP_HSCROLL_POLICY:
+ priv->hscroll_policy = g_value_get_enum (value);
+ gtk_widget_queue_resize (GTK_WIDGET (layout));
+ break;
+ case PROP_VSCROLL_POLICY:
+ priv->vscroll_policy = g_value_get_enum (value);
+ gtk_widget_queue_resize (GTK_WIDGET (layout));
break;
case PROP_WIDTH:
gtk_layout_set_size (layout, g_value_get_uint (value),
window = gdk_window_new (gtk_widget_get_parent_window (widget),
&attributes, attributes_mask);
gtk_widget_set_window (widget, window);
- gdk_window_set_user_data (window, widget);
+ gtk_widget_register_window (widget, window);
gtk_widget_get_allocation (widget, &allocation);
- attributes.x = - priv->hadjustment->value,
- attributes.y = - priv->vadjustment->value;
+ attributes.x = - gtk_adjustment_get_value (priv->hadjustment),
+ attributes.y = - gtk_adjustment_get_value (priv->vadjustment);
attributes.width = MAX (priv->width, allocation.width);
attributes.height = MAX (priv->height, allocation.height);
- attributes.event_mask = GDK_EXPOSURE_MASK | GDK_SCROLL_MASK |
+ attributes.event_mask = GDK_EXPOSURE_MASK | GDK_SCROLL_MASK |
+ GDK_SMOOTH_SCROLL_MASK |
gtk_widget_get_events (widget);
priv->bin_window = gdk_window_new (window,
&attributes, attributes_mask);
- gdk_window_set_user_data (priv->bin_window, widget);
-
- gtk_widget_style_attach (widget);
- gtk_style_set_background (gtk_widget_get_style (widget), priv->bin_window, GTK_STATE_NORMAL);
+ gtk_widget_register_window (widget, priv->bin_window);
+ gtk_style_context_set_background (gtk_widget_get_style_context (widget), priv->bin_window);
tmp_list = priv->children;
while (tmp_list)
}
static void
-gtk_layout_style_set (GtkWidget *widget,
- GtkStyle *old_style)
+gtk_layout_style_updated (GtkWidget *widget)
{
GtkLayoutPrivate *priv;
- GTK_WIDGET_CLASS (gtk_layout_parent_class)->style_set (widget, old_style);
+ GTK_WIDGET_CLASS (gtk_layout_parent_class)->style_updated (widget);
if (gtk_widget_get_realized (widget))
{
priv = GTK_LAYOUT (widget)->priv;
- gtk_style_set_background (gtk_widget_get_style (widget), priv->bin_window, GTK_STATE_NORMAL);
+ gtk_style_context_set_background (gtk_widget_get_style_context (widget), priv->bin_window);
}
}
GtkLayout *layout = GTK_LAYOUT (widget);
GtkLayoutPrivate *priv = layout->priv;
- gdk_window_set_user_data (priv->bin_window, NULL);
+ gtk_widget_unregister_window (widget, priv->bin_window);
gdk_window_destroy (priv->bin_window);
priv->bin_window = NULL;
GTK_WIDGET_CLASS (gtk_layout_parent_class)->unrealize (widget);
}
-static void
-gtk_layout_size_request (GtkWidget *widget,
- GtkRequisition *requisition)
+static void
+gtk_layout_get_preferred_width (GtkWidget *widget,
+ gint *minimum,
+ gint *natural)
{
- requisition->width = 0;
- requisition->height = 0;
+ *minimum = *natural = 0;
}
-static void
+static void
+gtk_layout_get_preferred_height (GtkWidget *widget,
+ gint *minimum,
+ gint *natural)
+{
+ *minimum = *natural = 0;
+}
+
+static void
gtk_layout_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
if (gtk_widget_get_realized (GTK_WIDGET (layout)))
{
gdk_window_move (priv->bin_window,
- - priv->hadjustment->value,
- - priv->vadjustment->value);
-
- gdk_window_process_updates (priv->bin_window, TRUE);
+ - gtk_adjustment_get_value (priv->hadjustment),
+ - gtk_adjustment_get_value (priv->vadjustment));
}
}