2008-10-20 Emmanuele Bassi <ebassi@linux.intel.com>
authorEmmanuele Bassi <ebassi@openedhand.com>
Mon, 20 Oct 2008 15:29:40 +0000 (15:29 +0000)
committerEmmanuele Bassi <ebassi@openedhand.com>
Mon, 20 Oct 2008 15:29:40 +0000 (15:29 +0000)
* clutter-gtk/Makefile.am:
* examples/Makefile.am: Update the build.

* clutter-gtk/clutter-gtk.h: Added a single include header, and
disabled the inclusion of specific headers; this keeps the
library clean and future-proof, now that we have more than one
header file.

* clutter-gtk/gtk-clutter-embed.h:
* clutter-gtk/gtk-clutter-util.h: Disabled the direct inclusion
of a single header file.

* clutter-gtk/gtk-clutter-scrollable.c:
* clutter-gtk/gtk-clutter-scrollable.h: Added a GtkClutterScrollable
interface for scrollable actors using GtkAdjustments.

* clutter-gtk/gtk-clutter-viewport.c:
* clutter-gtk/gtk-clutter-viewport.h: Added a scrollable actor
implementing GtkClutterScrollable.

* doc/reference/Makefile.am:
* doc/reference/clutter-gtk-docs.sgml:
* doc/reference/clutter-gtk-sections.txt:
* doc/reference/clutter-gtk.types: Update the documentation.

* examples/gtk-clutter-events.c:
* examples/gtk-clutter-multistage.c:
* examples/gtk-clutter-test.c: Update to include clutter-gtk.h.

* examples/gtk-clutter-viewport.c: Added an example of
the GtkClutterViewport usage.

18 files changed:
ChangeLog
clutter-gtk/Makefile.am
clutter-gtk/clutter-gtk.h [new file with mode: 0644]
clutter-gtk/gtk-clutter-embed.h
clutter-gtk/gtk-clutter-scrollable.c [new file with mode: 0644]
clutter-gtk/gtk-clutter-scrollable.h [new file with mode: 0644]
clutter-gtk/gtk-clutter-util.h
clutter-gtk/gtk-clutter-viewport.c [new file with mode: 0644]
clutter-gtk/gtk-clutter-viewport.h [new file with mode: 0644]
doc/reference/Makefile.am
doc/reference/clutter-gtk-docs.sgml
doc/reference/clutter-gtk-sections.txt
doc/reference/clutter-gtk.types
examples/Makefile.am
examples/gtk-clutter-events.c
examples/gtk-clutter-multistage.c
examples/gtk-clutter-test.c
examples/gtk-clutter-viewport.c [new file with mode: 0644]

index c219a9f..c330534 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,37 @@
+2008-10-20  Emmanuele Bassi  <ebassi@linux.intel.com>
+
+       * clutter-gtk/Makefile.am:
+       * examples/Makefile.am: Update the build.
+
+       * clutter-gtk/clutter-gtk.h: Added a single include header, and
+       disabled the inclusion of specific headers; this keeps the
+       library clean and future-proof, now that we have more than one
+       header file.
+
+       * clutter-gtk/gtk-clutter-embed.h:
+       * clutter-gtk/gtk-clutter-util.h: Disabled the direct inclusion
+       of a single header file.
+
+       * clutter-gtk/gtk-clutter-scrollable.c:
+       * clutter-gtk/gtk-clutter-scrollable.h: Added a GtkClutterScrollable
+       interface for scrollable actors using GtkAdjustments.
+
+       * clutter-gtk/gtk-clutter-viewport.c:
+       * clutter-gtk/gtk-clutter-viewport.h: Added a scrollable actor
+       implementing GtkClutterScrollable.
+
+       * doc/reference/Makefile.am:
+       * doc/reference/clutter-gtk-docs.sgml:
+       * doc/reference/clutter-gtk-sections.txt:
+       * doc/reference/clutter-gtk.types: Update the documentation.
+
+       * examples/gtk-clutter-events.c:
+       * examples/gtk-clutter-multistage.c:
+       * examples/gtk-clutter-test.c: Update to include clutter-gtk.h.
+
+       * examples/gtk-clutter-viewport.c: Added an example of
+       the GtkClutterViewport usage.
+
 2008-10-15  Emmanuele Bassi  <ebassi@linux.intel.com>
 
        * configure.ac: Bump up to 0.9 now that we've branched.
index d516d09..1f487e0 100644 (file)
@@ -4,16 +4,33 @@ INCLUDES = \
        -DG_LOG_DOMAIN=\"Clutter-Gtk\"          \
        -DPREFIX=\""$(prefix)"\"                \
        -DLIBDIR=\""$(libdir)"\"                \
+        -DCLUTTER_GTK_COMPILATION               \
+        -DG_DISABLE_DEPRECATED                  \
+        -DGDK_PIXBUF_DISABLE_DEPRECATED         \
+        -DGDK_DISABLE_DEPRECATED                \
+        -DGTK_DISABLE_DEPRECATED                \
        $(CLUTTER_DEBUG_FLAGS)                  \
        $(GCC_FLAGS)                            \
        $(CLUTTER_CFLAGS)                       \
        $(GTK_CFLAGS)
 
-lib_LTLIBRARIES = libclutter-gtk-0.8.la
+lib_LTLIBRARIES = libclutter-gtk-0.9.la
 
-libclutter_gtk_0_8_la_SOURCES = gtk-clutter-embed.c gtk-clutter-util.c
-libclutter_gtk_0_8_la_LIBADD = $(CLUTTER_LIBS) $(GTK_LIBS)
-libclutter_gtk_0_8_la_LDFLAGS = $(CLUTTER_LT_LDFLAGS)
+# please, keep the list sorted alphabetically
+libclutter_gtk_0_9_la_SOURCES = \
+        gtk-clutter-embed.c \
+        gtk-clutter-scrollable.c \
+        gtk-clutter-util.c \
+        gtk-clutter-viewport.c
+libclutter_gtk_0_9_la_LIBADD = $(CLUTTER_LIBS) $(GTK_LIBS)
+libclutter_gtk_0_9_la_LDFLAGS = $(CLUTTER_LT_LDFLAGS)
 
-cluttergtkheadersdir = $(includedir)/clutter-0.8/clutter-gtk
-cluttergtkheaders_HEADERS = gtk-clutter-embed.h gtk-clutter-util.h
+cluttergtkheadersdir = $(includedir)/clutter-0.9/clutter-gtk
+
+# please, keep the list sorted alphabetically
+cluttergtkheaders_HEADERS = \
+        clutter-gtk.h \
+        gtk-clutter-embed.h \
+        gtk-clutter-scrollable.h \
+        gtk-clutter-util.h \
+        gtk-clutter-viewport.h
diff --git a/clutter-gtk/clutter-gtk.h b/clutter-gtk/clutter-gtk.h
new file mode 100644 (file)
index 0000000..c4b8c7a
--- /dev/null
@@ -0,0 +1,15 @@
+#ifndef __CLUTTER_GTK_H__
+#define __CLUTTER_GTK_H__
+
+#define __CLUTTER_GTK_H_INSIDE__
+
+/* Please, keep the list sorted alphabetically */
+
+#include "gtk-clutter-embed.h"
+#include "gtk-clutter-scrollable.h"
+#include "gtk-clutter-util.h"
+#include "gtk-clutter-viewport.h"
+
+#undef __CLUTTER_GTK_H_INSIDE__
+
+#endif /* __CLUTTER_GTK_H__ */
index 435bf3a..4536add 100644 (file)
  *   Emmanuele Bassi  <ebassi@openedhand.com>
  */
 
+#if !defined(__CLUTTER_GTK_H_INSIDE__) && !defined(CLUTTER_GTK_COMPILATION)
+#error "Only <clutter-gtk/clutter-gtk.h> can be included directly."
+#endif
+
 #ifndef __GTK_CLUTTER_EMBED_H__
 #define __GTK_CLUTTER_EMBED_H__
 
-#include <gtk/gtkwidget.h>
-#include <clutter/clutter-main.h>
-#include <clutter/clutter-actor.h>
-#include <clutter-gtk/gtk-clutter-util.h>
+#include <gtk/gtk.h>
+#include <clutter/clutter.h>
 
 G_BEGIN_DECLS
 
diff --git a/clutter-gtk/gtk-clutter-scrollable.c b/clutter-gtk/gtk-clutter-scrollable.c
new file mode 100644 (file)
index 0000000..7e87c3a
--- /dev/null
@@ -0,0 +1,136 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "gtk-clutter-scrollable.h"
+
+#define I_(str) (g_intern_static_string ((str)))
+
+/**
+ * SECTION:gtk-clutter-scrollable
+ * @short_description: Interface for scrollable actors
+ *
+ * FIXME
+ *
+ * #GtkClutterScrollable is available since Clutter-GTK 1.0
+ */
+
+static void
+gtk_clutter_scrollable_base_init (gpointer g_iface)
+{
+  static gboolean is_initialized = FALSE;
+
+  if (G_UNLIKELY (!is_initialized))
+    {
+      GParamSpec *pspec;
+
+      /**
+       * GtkClutterScrollable:hadjustment:
+       *
+       * The #GtkAdjustment that determines the value of the
+       * horizontal position for this scrollable actor.
+       *
+       * Since: 1.0
+       */
+      pspec = g_param_spec_object ("hadjustment",
+                                   "Horizontal adjustment",
+                                   "The GtkAdjustment that determines "
+                                   "the value of the horizontal position "
+                                   "for this scrollable actor",
+                                   GTK_TYPE_ADJUSTMENT,
+                                   G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
+      g_object_interface_install_property (g_iface, pspec);
+
+      /**
+       * GtkClutterScrollable:vadjustment:
+       *
+       * The #GtkAdjustment that determines the value of the
+       * vertical position for this scrollable actor.
+       *
+       * Since: 1.0
+       */
+      pspec = g_param_spec_object ("vadjustment",
+                                   "Vertical adjustment",
+                                   "The GtkAdjustment that determines "
+                                   "the value of the vertical position "
+                                   "for this scrollable actor",
+                                   GTK_TYPE_ADJUSTMENT,
+                                   G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
+      g_object_interface_install_property (g_iface, pspec);
+
+      is_initialized = TRUE;
+    }
+}
+
+GType
+gtk_clutter_scrollable_get_type (void)
+{
+  static GType scrollable_type = 0;
+
+  if (G_UNLIKELY (!scrollable_type))
+    {
+      const GTypeInfo scrollable_info =
+      {
+        sizeof (GtkClutterScrollableIface),
+        (GBaseInitFunc)     gtk_clutter_scrollable_base_init,
+        (GBaseFinalizeFunc) NULL,
+      };
+
+      scrollable_type = g_type_register_static (G_TYPE_INTERFACE,
+                                                I_("GtkClutterScrollable"),
+                                                &scrollable_info, 0);
+    }
+
+  return scrollable_type;
+}
+
+/**
+ * gtk_clutter_scrollable_set_adjustments:
+ * @scrollable: a #GtkClutterScrollable
+ * @h_adjust: a #GtkAdjustment, or %NULL
+ * @v_adjust: a #GtkAdjustment, or %NULL
+ *
+ * Sets the horizontal and vertical adjustments used to determine
+ * the position of the scrollable actor.
+ *
+ * Since: 1.0
+ */
+void
+gtk_clutter_scrollable_set_adjustments (GtkClutterScrollable *scrollable,
+                                        GtkAdjustment        *h_adjust,
+                                        GtkAdjustment        *v_adjust)
+{
+  GtkClutterScrollableIface *iface;
+
+  g_return_if_fail (GTK_IS_CLUTTER_SCROLLABLE (scrollable));
+  g_return_if_fail (h_adjust == NULL || GTK_IS_ADJUSTMENT (h_adjust));
+
+  iface = GTK_CLUTTER_SCROLLABLE_GET_IFACE (scrollable);
+  if (iface->set_adjustments)
+    iface->set_adjustments (scrollable, h_adjust, v_adjust);
+}
+
+/**
+ * gtk_clutter_scrollable_get_adjustments:
+ * @scrollable: a #GtkClutterScrollable
+ * @h_adjust: return location for a #GtkAdjustment, or %NULL
+ * @v_adjust: return location for a #GtkAdjustment, or %NULL
+ *
+ * Retrieves the horizontal and vertical adjustments used to
+ * determine the position of the scrollable actor.
+ *
+ * Since: 1.0
+ */
+void
+gtk_clutter_scrollable_get_adjustments (GtkClutterScrollable  *scrollable,
+                                        GtkAdjustment        **h_adjust,
+                                        GtkAdjustment        **v_adjust)
+{
+  GtkClutterScrollableIface *iface;
+
+  g_return_if_fail (GTK_IS_CLUTTER_SCROLLABLE (scrollable));
+
+  iface = GTK_CLUTTER_SCROLLABLE_GET_IFACE (scrollable);
+  if (iface->get_adjustments)
+    iface->get_adjustments (scrollable, h_adjust, v_adjust);
+}
diff --git a/clutter-gtk/gtk-clutter-scrollable.h b/clutter-gtk/gtk-clutter-scrollable.h
new file mode 100644 (file)
index 0000000..1eb53d6
--- /dev/null
@@ -0,0 +1,84 @@
+/* gtk-clutter-scrollable.h: Interface for scrollable actors
+ *
+ * Copyright (C) 2008  Intel Corp.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * 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.
+ *
+ * Author:
+ *   Emmanuele Bassi <ebassi@linux.intel.com>
+ *
+ * Based on similar code by:
+ *   Chris Lord <chris@openedhand.com>
+ */
+
+#if !defined(__CLUTTER_GTK_H_INSIDE__) && !defined(CLUTTER_GTK_COMPILATION)
+#error "Only <clutter-gtk/clutter-gtk.h> can be included directly."
+#endif
+
+#ifndef __GTK_CLUTTER_SCROLLABLE_H__
+#define __GTK_CLUTTER_SCROLLABLE_H__
+
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_CLUTTER_SCROLLABLE             (gtk_clutter_scrollable_get_type ())
+#define GTK_CLUTTER_SCROLLABLE(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_CLUTTER_SCROLLABLE, GtkClutterScrollable))
+#define GTK_IS_CLUTTER_SCROLLABLE(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_CLUTTER_SCROLLABLE))
+#define GTK_CLUTTER_SCROLLABLE_GET_IFACE(obj)   (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GTK_TYPE_CLUTTER_SCROLLABLE, GtkClutterScrollableIface))
+
+typedef struct _GtkClutterScrollable            GtkClutterScrollable; /* dummy */
+typedef struct _GtkClutterScrollableIface       GtkClutterScrollableIface;
+
+/**
+ * GtkClutterScrollableIface:
+ * @set_adjustments: virtual function for setting the horizontal
+ *   and vertical adjustments of a #GtkClutterScrollable
+ * @get_adjustments: virtual function for retrieving the horizontal
+ *   and vertical adjustments of a #GtkClutterScrollable
+ *
+ * The #GtkClutterScrollableIface structure contains only private data
+ * and should be accessed using the provided functions.
+ *
+ * Since: 0.8.2
+ */
+struct _GtkClutterScrollableIface
+{
+  /*< private >*/
+  GTypeInterface parent_iface;
+
+  /*< public >*/
+  void (* set_adjustments) (GtkClutterScrollable  *scrollable,
+                            GtkAdjustment         *h_adjust,
+                            GtkAdjustment         *v_adjust);
+  void (* get_adjustments) (GtkClutterScrollable  *scrollable,
+                            GtkAdjustment        **h_adjust,
+                            GtkAdjustment        **v_adjust);
+};
+
+GType gtk_clutter_scrollable_get_type (void) G_GNUC_CONST;
+
+void gtk_clutter_scrollable_set_adjustments (GtkClutterScrollable  *scrollable,
+                                             GtkAdjustment         *h_adjust,
+                                             GtkAdjustment         *v_adjust);
+void gtk_clutter_scrollable_get_adjustments (GtkClutterScrollable  *scrollable,
+                                             GtkAdjustment        **h_adjust,
+                                             GtkAdjustment        **v_adjust);
+
+G_END_DECLS
+
+#endif /* __GTK_CLUTTER_SCROLLABLE_H__ */
index 61473c4..8d60c90 100644 (file)
  *   Emmanuele Bassi  <ebassi@openedhand.com>
  */
 
+#if !defined(__CLUTTER_GTK_H_INSIDE__) && !defined(CLUTTER_GTK_COMPILATION)
+#error "Only <clutter-gtk/clutter-gtk.h> can be included directly."
+#endif
+
 #ifndef __GTK_CLUTTER_UTIL_H__
 #define __GTK_CLUTTER_UTIL_H__
 
diff --git a/clutter-gtk/gtk-clutter-viewport.c b/clutter-gtk/gtk-clutter-viewport.c
new file mode 100644 (file)
index 0000000..a929cbd
--- /dev/null
@@ -0,0 +1,712 @@
+/**
+ * SECTION:gtk-clutter-viewport
+ * @short_description: A scrollable actor
+ *
+ * #GtkClutterViewport is a scrollable actor that can contain a single
+ * #ClutterActor. Using two #GtkAdjustment<!-- -->s it is possible to
+ * control the visible area of the child actor if the size of the viewport
+ * is smaller than the size of the child.
+ *
+ * The #GtkAdjustment<!-- -->s used to control the horizontal and
+ * vertical scrolling can be attached to a #GtkScrollbar subclass,
+ * like #GtkHScrollbar or #GtkVScrollbar.
+ *
+ * The #GtkClutterViewport can be used inside any #ClutterContainer
+ * implementation.
+ *
+ * #GtkClutterViewport is available since Clutter-GTK 1.0
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <cogl/cogl.h>
+
+#include "gtk-clutter-scrollable.h"
+#include "gtk-clutter-util.h"
+#include "gtk-clutter-viewport.h"
+
+/* XXX - GtkAdjustment accessors have been added with GTK+ 2.14,
+ * but I want Clutter-GTK to be future-proof, so let's do this
+ * little #define dance.
+ */
+#if !GTK_CHECK_VERSION (2, 14, 0)
+#define gtk_adjustment_set_page_size(a,v)       ((a)->page_size = (v))
+#define gtk_adjustment_set_upper(a,v)           ((a)->upper = (v))
+#define gtk_adjustment_set_page_increment(a,v)  ((a)->page_increment = (v))
+#define gtk_adjustment_set_step_increment(a,v)  ((a)->step_increment = (v))
+#define gtk_adjustment_set_lower(a,v)           ((a)->lower = (v))
+
+#define gtk_adjustment_get_upper(a)             ((a)->upper)
+#define gtk_adjustment_get_page_size(a)         ((a)->page_size)
+#endif
+
+#define GET_PRIVATE(obj)        (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_CLUTTER_VIEWPORT, GtkClutterViewportPrivate))
+
+#define I_(str) (g_intern_static_string ((str)))
+
+static void clutter_container_iface_init      (gpointer g_iface);
+static void gtk_clutter_scrollable_iface_init (gpointer g_iface);
+
+G_DEFINE_TYPE_WITH_CODE (GtkClutterViewport,
+                         gtk_clutter_viewport,
+                         CLUTTER_TYPE_ACTOR,
+                         G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_CONTAINER,
+                                                clutter_container_iface_init)
+                         G_IMPLEMENT_INTERFACE (GTK_TYPE_CLUTTER_SCROLLABLE,
+                                                gtk_clutter_scrollable_iface_init));
+
+struct _GtkClutterViewportPrivate
+{
+  ClutterVertex origin;
+
+  ClutterActor *child;
+
+  GtkAdjustment *h_adjustment;
+  GtkAdjustment *v_adjustment;
+};
+
+enum
+{
+  PROP_0,
+
+  PROP_CHILD,
+  PROP_ORIGIN,
+  PROP_H_ADJUSTMENT,
+  PROP_V_ADJUSTMENT
+};
+
+static void
+gtk_clutter_viewport_add (ClutterContainer *container,
+                          ClutterActor     *actor)
+{
+  GtkClutterViewportPrivate *priv = GTK_CLUTTER_VIEWPORT (container)->priv;
+
+  if (priv->child)
+    clutter_actor_unparent (priv->child);
+
+  clutter_actor_set_parent (actor, CLUTTER_ACTOR (container));
+  priv->child = actor;
+
+  clutter_actor_queue_relayout (CLUTTER_ACTOR (container));
+
+  g_signal_emit_by_name (container, "actor-added", actor);
+  g_object_notify (G_OBJECT (container), "child");
+}
+
+static void
+gtk_clutter_viewport_remove (ClutterContainer *container,
+                             ClutterActor     *actor)
+{
+  GtkClutterViewportPrivate *priv = GTK_CLUTTER_VIEWPORT (container)->priv;
+
+  if (G_LIKELY (priv->child == actor))
+    {
+      g_object_ref (actor);
+
+      clutter_actor_unparent (actor);
+      priv->child = NULL;
+
+      clutter_actor_queue_relayout (CLUTTER_ACTOR (container));
+
+      g_signal_emit_by_name (container, "actor-removed", actor);
+
+      g_object_unref (actor);
+    }
+}
+
+static void
+gtk_clutter_viewport_foreach (ClutterContainer *container,
+                              ClutterCallback   callback,
+                              gpointer          callback_data)
+{
+  GtkClutterViewportPrivate *priv = GTK_CLUTTER_VIEWPORT (container)->priv;
+
+  if (G_LIKELY (priv->child))
+    callback (priv->child, callback_data);
+}
+
+static void
+clutter_container_iface_init (gpointer g_iface)
+{
+  ClutterContainerIface *iface = g_iface;
+
+  iface->add = gtk_clutter_viewport_add;
+  iface->remove = gtk_clutter_viewport_remove;
+  iface->foreach = gtk_clutter_viewport_foreach;
+}
+
+static void
+viewport_adjustment_value_changed (GtkAdjustment      *adjustment,
+                                   GtkClutterViewport *viewport)
+{
+  GtkClutterViewportPrivate *priv = viewport->priv;
+
+  if (priv->child && CLUTTER_ACTOR_IS_VISIBLE (priv->child))
+    {
+      GtkAdjustment *h_adjust = priv->h_adjustment;
+      GtkAdjustment *v_adjust = priv->v_adjustment;
+      ClutterUnit new_x, new_y;
+
+      new_x = CLUTTER_UNITS_FROM_FLOAT (gtk_adjustment_get_value (h_adjust));
+      new_y = CLUTTER_UNITS_FROM_FLOAT (gtk_adjustment_get_value (v_adjust));
+
+      /* change the origin and queue a relayout */
+      if (new_x != priv->origin.x || new_y != priv->origin.y)
+        {
+          priv->origin.x = new_x;
+          priv->origin.y = new_y;
+
+          clutter_actor_queue_relayout (CLUTTER_ACTOR (viewport));
+        }
+    }
+}
+
+static gboolean
+viewport_reclamp_adjustment (GtkAdjustment *adjustment)
+{
+  gdouble value = gtk_adjustment_get_value (adjustment);
+  gdouble limit;
+
+  limit = gtk_adjustment_get_upper (adjustment)
+        - gtk_adjustment_get_page_size (adjustment);
+
+  value = CLAMP (value, 0, limit);
+  if (value != gtk_adjustment_get_value (adjustment))
+    {
+      gtk_adjustment_set_value (adjustment, value);
+      return TRUE;
+    }
+  else
+    return FALSE;
+}
+
+static gboolean
+viewport_set_hadjustment_values (GtkClutterViewport *viewport)
+{
+  GtkClutterViewportPrivate *priv = viewport->priv;
+  GtkAdjustment *h_adjust = priv->h_adjustment;
+  guint width;
+
+  width = clutter_actor_get_width (CLUTTER_ACTOR (viewport));
+
+  gtk_adjustment_set_page_size (h_adjust, width);
+  gtk_adjustment_set_step_increment (h_adjust, width * 0.1);
+  gtk_adjustment_set_page_increment (h_adjust, width * 0.9);
+  gtk_adjustment_set_lower (h_adjust, 0);
+
+  if (priv->child && CLUTTER_ACTOR_IS_VISIBLE (priv->child))
+    {
+      ClutterUnit natural_width;
+
+      clutter_actor_get_preferred_size (priv->child,
+                                        NULL, NULL,
+                                        &natural_width, NULL);
+
+      gtk_adjustment_set_upper (h_adjust,
+                                MAX (CLUTTER_UNITS_TO_DEVICE (natural_width),
+                                     width));
+    }
+  else
+    gtk_adjustment_set_upper (h_adjust, width);
+
+  return viewport_reclamp_adjustment (h_adjust);
+}
+
+static gboolean
+viewport_set_vadjustment_values (GtkClutterViewport *viewport)
+{
+  GtkClutterViewportPrivate *priv = viewport->priv;
+  GtkAdjustment *v_adjust = priv->v_adjustment;
+  guint height;
+
+  height = clutter_actor_get_height (CLUTTER_ACTOR (viewport));
+
+  gtk_adjustment_set_page_size (v_adjust, height);
+  gtk_adjustment_set_step_increment (v_adjust, height * 0.1);
+  gtk_adjustment_set_page_increment (v_adjust, height * 0.9);
+  gtk_adjustment_set_lower (v_adjust, 0);
+
+  if (priv->child && CLUTTER_ACTOR_IS_VISIBLE (priv->child))
+    {
+      ClutterUnit natural_height;
+
+      clutter_actor_get_preferred_size (priv->child,
+                                        NULL, NULL,
+                                        NULL, &natural_height);
+
+      gtk_adjustment_set_upper (v_adjust,
+                                MAX (CLUTTER_UNITS_TO_DEVICE (natural_height),
+                                     height));
+    }
+  else
+    gtk_adjustment_set_upper (v_adjust, height);
+
+  return viewport_reclamp_adjustment (v_adjust);
+}
+
+static inline void
+disconnect_adjustment (GtkClutterViewport *viewport,
+                       GtkOrientation      orientation)
+{
+  GtkClutterViewportPrivate *priv = viewport->priv;
+  GtkAdjustment **adj_p;
+
+  adj_p = (orientation == GTK_ORIENTATION_HORIZONTAL) ? &priv->h_adjustment
+                                                      : &priv->v_adjustment;
+
+  if (*adj_p)
+    {
+      g_signal_handlers_disconnect_by_func (*adj_p,
+                                            viewport_adjustment_value_changed,
+                                            viewport);
+      g_object_unref (*adj_p);
+      *adj_p = NULL;
+    }
+}
+
+static inline void
+connect_adjustment (GtkClutterViewport *viewport,
+                    GtkOrientation      orientation,
+                    GtkAdjustment      *adjustment)
+{
+  GtkClutterViewportPrivate *priv = viewport->priv;
+  GtkAdjustment **adj_p;
+  gboolean value_changed = FALSE;
+
+  adj_p = (orientation == GTK_ORIENTATION_HORIZONTAL) ? &priv->h_adjustment
+                                                      : &priv->v_adjustment;
+
+  if (adjustment && adjustment == *adj_p)
+    return;
+
+  if (!adjustment)
+    adjustment = GTK_ADJUSTMENT (gtk_adjustment_new (0, 0, 0, 0, 0, 0));
+
+  disconnect_adjustment (viewport, orientation);
+  *adj_p = g_object_ref_sink (adjustment);
+
+  if (orientation == GTK_ORIENTATION_HORIZONTAL)
+    value_changed = viewport_set_hadjustment_values (viewport);
+  else
+    value_changed = viewport_set_vadjustment_values (viewport);
+
+  g_signal_connect (adjustment, "value-changed",
+                    G_CALLBACK (viewport_adjustment_value_changed),
+                    viewport);
+
+  gtk_adjustment_changed (adjustment);
+
+  if (value_changed)
+    gtk_adjustment_value_changed (adjustment);
+  else
+    viewport_adjustment_value_changed (adjustment, viewport);
+
+  if (orientation == GTK_ORIENTATION_HORIZONTAL)
+    g_object_notify (G_OBJECT (viewport), "hadjustment");
+  else
+    g_object_notify (G_OBJECT (viewport), "vadjustment");
+}
+
+static void
+gtk_clutter_viewport_set_adjustments (GtkClutterScrollable *scrollable,
+                                      GtkAdjustment        *h_adjust,
+                                      GtkAdjustment        *v_adjust)
+{
+  g_object_freeze_notify (G_OBJECT (scrollable));
+
+  connect_adjustment (GTK_CLUTTER_VIEWPORT (scrollable),
+                      GTK_ORIENTATION_HORIZONTAL,
+                      h_adjust);
+  connect_adjustment (GTK_CLUTTER_VIEWPORT (scrollable),
+                      GTK_ORIENTATION_VERTICAL,
+                      v_adjust);
+
+  g_object_thaw_notify (G_OBJECT (scrollable));
+}
+
+static void
+gtk_clutter_viewport_get_adjustments (GtkClutterScrollable  *scrollable,
+                                      GtkAdjustment        **h_adjust,
+                                      GtkAdjustment        **v_adjust)
+{
+  GtkClutterViewportPrivate *priv = GTK_CLUTTER_VIEWPORT (scrollable)->priv;
+
+  if (h_adjust)
+    *h_adjust = priv->h_adjustment;
+
+  if (v_adjust)
+    *v_adjust = priv->v_adjustment;
+}
+
+static void
+gtk_clutter_scrollable_iface_init (gpointer g_iface)
+{
+  GtkClutterScrollableIface *iface = g_iface;
+
+  iface->set_adjustments = gtk_clutter_viewport_set_adjustments;
+  iface->get_adjustments = gtk_clutter_viewport_get_adjustments;
+}
+
+static void
+gtk_clutter_viewport_set_property (GObject      *gobject,
+                                   guint         prop_id,
+                                   const GValue *value,
+                                   GParamSpec   *pspec)
+{
+  GtkClutterViewportPrivate *priv = GTK_CLUTTER_VIEWPORT (gobject)->priv;
+
+  switch (prop_id)
+    {
+    case PROP_CHILD:
+      clutter_container_add_actor (CLUTTER_CONTAINER (gobject),
+                                   g_value_get_object (value));
+      break;
+
+    case PROP_ORIGIN:
+      {
+        ClutterVertex *v = g_value_get_boxed (value);
+
+        priv->origin = *v;
+
+        if (CLUTTER_ACTOR_IS_VISIBLE (gobject))
+          clutter_actor_queue_redraw (CLUTTER_ACTOR (gobject));
+      }
+      break;
+
+    case PROP_H_ADJUSTMENT:
+      connect_adjustment (GTK_CLUTTER_VIEWPORT (gobject),
+                          GTK_ORIENTATION_HORIZONTAL,
+                          g_value_get_object (value));
+      break;
+
+    case PROP_V_ADJUSTMENT:
+      connect_adjustment (GTK_CLUTTER_VIEWPORT (gobject),
+                          GTK_ORIENTATION_VERTICAL,
+                          g_value_get_object (value));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+gtk_clutter_viewport_get_property (GObject    *gobject,
+                                   guint       prop_id,
+                                   GValue     *value,
+                                   GParamSpec *pspec)
+{
+  GtkClutterViewportPrivate *priv = GTK_CLUTTER_VIEWPORT (gobject)->priv;
+
+  switch (prop_id)
+    {
+    case PROP_CHILD:
+      g_value_set_object (value, priv->child);
+      break;
+
+    case PROP_ORIGIN:
+      g_value_set_boxed (value, &priv->origin);
+      break;
+
+    case PROP_H_ADJUSTMENT:
+      g_value_set_object (value, priv->h_adjustment);
+      break;
+
+    case PROP_V_ADJUSTMENT:
+      g_value_set_object (value, priv->v_adjustment);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+gtk_clutter_viewport_dispose (GObject *gobject)
+{
+  GtkClutterViewportPrivate *priv = GTK_CLUTTER_VIEWPORT (gobject)->priv;
+
+  if (priv->child)
+    {
+      clutter_actor_destroy (priv->child);
+      priv->child = NULL;
+    }
+
+  disconnect_adjustment (GTK_CLUTTER_VIEWPORT (gobject),
+                         GTK_ORIENTATION_HORIZONTAL);
+  disconnect_adjustment (GTK_CLUTTER_VIEWPORT (gobject),
+                         GTK_ORIENTATION_VERTICAL);
+
+  G_OBJECT_CLASS (gtk_clutter_viewport_parent_class)->dispose (gobject);
+}
+
+static void
+gtk_clutter_viewport_get_preferred_width (ClutterActor *actor,
+                                          ClutterUnit   for_height,
+                                          ClutterUnit  *min_width_p,
+                                          ClutterUnit  *natural_width_p)
+{
+  GtkClutterViewportPrivate *priv = GTK_CLUTTER_VIEWPORT (actor)->priv;
+
+  /* if we have a child, we want to be as big as the child
+   * wishes to be; otherwise, we don't have a preferred width
+   */
+  if (priv->child)
+    clutter_actor_get_preferred_width (priv->child, for_height,
+                                       min_width_p,
+                                       natural_width_p);
+  else
+    {
+      if (min_width_p)
+        *min_width_p = 0;
+
+      if (natural_width_p)
+        *natural_width_p = 0;
+    }
+}
+
+static void
+gtk_clutter_viewport_get_preferred_height (ClutterActor *actor,
+                                           ClutterUnit   for_width,
+                                           ClutterUnit  *min_height_p,
+                                           ClutterUnit  *natural_height_p)
+{
+  GtkClutterViewportPrivate *priv = GTK_CLUTTER_VIEWPORT (actor)->priv;
+
+  /* if we have a child, we want to be as big as the child
+   * wishes to be; otherwise, we don't have a preferred height
+   */
+  if (priv->child)
+    clutter_actor_get_preferred_height (priv->child, for_width,
+                                        min_height_p,
+                                        natural_height_p);
+  else
+    {
+      if (min_height_p)
+        *min_height_p = 0;
+
+      if (natural_height_p)
+        *natural_height_p = 0;
+    }
+}
+
+static void
+gtk_clutter_viewport_allocate (ClutterActor          *actor,
+                               const ClutterActorBox *box,
+                               gboolean               origin_changed)
+{
+  GtkClutterViewport *viewport = GTK_CLUTTER_VIEWPORT (actor);
+  GtkClutterViewportPrivate *priv = viewport->priv;
+  ClutterActorClass *parent_class;
+  gboolean h_adjustment_value_changed, v_adjustment_value_changed;
+
+  parent_class = CLUTTER_ACTOR_CLASS (gtk_clutter_viewport_parent_class);
+  parent_class->allocate (actor, box, origin_changed);
+
+  h_adjustment_value_changed = viewport_set_hadjustment_values (viewport);
+  v_adjustment_value_changed = viewport_set_vadjustment_values (viewport);
+
+  if (priv->child)
+    {
+      ClutterActorBox child_allocation = { 0, };
+      ClutterUnit alloc_width, alloc_height;
+
+      /* a viewport is a boundless actor which can contain a child
+       * without constraints; hence, we give any child exactly the
+       * wanted natural size, no matter how small the viewport
+       * actually is.
+       */
+      clutter_actor_get_preferred_size (priv->child,
+                                        NULL, NULL,
+                                        &alloc_width, &alloc_height);
+
+      child_allocation.x1 = clutter_actor_get_xu (priv->child);
+      child_allocation.y1 = clutter_actor_get_yu (priv->child);
+      child_allocation.x2 = child_allocation.x1 + alloc_width;
+      child_allocation.y2 = child_allocation.y1 + alloc_height;
+
+      clutter_actor_allocate (priv->child, &child_allocation, origin_changed);
+    }
+
+  gtk_adjustment_changed (priv->h_adjustment);
+  gtk_adjustment_changed (priv->v_adjustment);
+
+  if (h_adjustment_value_changed)
+    gtk_adjustment_value_changed (priv->h_adjustment);
+
+  if (v_adjustment_value_changed)
+    gtk_adjustment_value_changed (priv->v_adjustment);
+}
+
+static void
+gtk_clutter_viewport_paint (ClutterActor *actor)
+{
+  GtkClutterViewportPrivate *priv = GTK_CLUTTER_VIEWPORT (actor)->priv;
+
+  cogl_push_matrix ();
+
+  /* translate the paint environment by the same amount
+   * defined by the origin value
+   */
+  cogl_translatex (CLUTTER_UNITS_TO_FIXED (priv->origin.x) * -1,
+                   CLUTTER_UNITS_TO_FIXED (priv->origin.y) * -1,
+                   CLUTTER_UNITS_TO_FIXED (priv->origin.z) * -1);
+
+  /* the child will be painted in the new frame of reference */
+  if (priv->child && CLUTTER_ACTOR_IS_VISIBLE (priv->child))
+    clutter_actor_paint (priv->child);
+
+  cogl_pop_matrix ();
+}
+
+static void
+gtk_clutter_viewport_pick (ClutterActor       *actor,
+                           const ClutterColor *pick_color)
+{
+  /* chain up to get the default pick */
+  CLUTTER_ACTOR_CLASS (gtk_clutter_viewport_parent_class)->pick (actor, pick_color);
+
+  /* this will cause the child (if any) to be painted in pick mode */
+  gtk_clutter_viewport_paint (actor);
+}
+
+static void
+gtk_clutter_viewport_class_init (GtkClutterViewportClass *klass)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+  ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
+  GParamSpec *pspec;
+
+  g_type_class_add_private (klass, sizeof (GtkClutterViewportPrivate));
+
+  gobject_class->set_property = gtk_clutter_viewport_set_property;
+  gobject_class->get_property = gtk_clutter_viewport_get_property;
+  gobject_class->dispose = gtk_clutter_viewport_dispose;
+
+  actor_class->get_preferred_width = gtk_clutter_viewport_get_preferred_width;
+  actor_class->get_preferred_height = gtk_clutter_viewport_get_preferred_height;
+  actor_class->allocate = gtk_clutter_viewport_allocate;
+  actor_class->paint = gtk_clutter_viewport_paint;
+  actor_class->pick = gtk_clutter_viewport_pick;
+
+  /**
+   * GtkClutterViewport:child:
+   *
+   * The #ClutterActor inside the viewport.
+   *
+   * Since: 1.0
+   */
+  pspec = g_param_spec_object ("child",
+                               "Child",
+                               "The ClutterActor inside the viewport",
+                               CLUTTER_TYPE_ACTOR,
+                               G_PARAM_READWRITE);
+  g_object_class_install_property (gobject_class, PROP_CHILD, pspec);
+
+  /**
+   * GtkClutterViewport:origin:
+   *
+   * The current origin of the viewport.
+   *
+   * Since: 1.0
+   */
+  pspec = g_param_spec_boxed ("origin",
+                              "Origin",
+                              "The current origin of the viewport",
+                              CLUTTER_TYPE_VERTEX,
+                              G_PARAM_READABLE);
+  g_object_class_install_property (gobject_class, PROP_ORIGIN, pspec);
+
+  /* GtkClutterScrollable properties */
+  g_object_class_override_property (gobject_class, PROP_H_ADJUSTMENT, "hadjustment");
+  g_object_class_override_property (gobject_class, PROP_V_ADJUSTMENT, "vadjustment");
+}
+
+static void
+gtk_clutter_viewport_init (GtkClutterViewport *viewport)
+{
+  GtkClutterViewportPrivate *priv;
+
+  viewport->priv = priv = GET_PRIVATE (viewport);
+}
+
+/**
+ * gtk_clutter_viewport_new:
+ * @h_adjust: horizontal adjustment, or %NULL
+ * @v_adjust: vertical adjustment, or %NULL
+ *
+ * Creates a new #GtkClutterViewport with the given adjustments.
+ *
+ * Return value: the newly created viewport actor
+ *
+ * Since: 1.0
+ */
+ClutterActor *
+gtk_clutter_viewport_new (GtkAdjustment *h_adjust,
+                          GtkAdjustment *v_adjust)
+{
+  return g_object_new (GTK_TYPE_CLUTTER_VIEWPORT,
+                       "hadjustment", h_adjust,
+                       "vadjustment", v_adjust,
+                       NULL);
+}
+
+/**
+ * gtk_clutter_viewport_get_origin:
+ * @viewport: a #GtkClutterViewport
+ * @x: return location for the X origin in pixels, or %NULL
+ * @y: return location for the Y origin in pixels, or %NULL
+ * @z: return location for the Z origin in pixels, or %NULL
+ *
+ * Retrieves the current translation factor ("origin") used when
+ * displaying the child of @viewport.
+ *
+ * Since: 1.0.
+ */
+void
+gtk_clutter_viewport_get_origin (GtkClutterViewport *viewport,
+                                 gint               *x,
+                                 gint               *y,
+                                 gint               *z)
+{
+  GtkClutterViewportPrivate *priv;
+
+  g_return_if_fail (GTK_IS_CLUTTER_VIEWPORT (viewport));
+
+  priv = viewport->priv;
+
+  if (x)
+    *x = CLUTTER_UNITS_TO_DEVICE (priv->origin.x);
+
+  if (y)
+    *y = CLUTTER_UNITS_TO_DEVICE (priv->origin.y);
+
+  if (z)
+    *z = CLUTTER_UNITS_TO_DEVICE (priv->origin.z);
+}
+
+/**
+ * gtk_clutter_viewport_get_originu:
+ * @viewport: a #GtkClutterViewport
+ * @origin: a #ClutterVertex
+ *
+ * Retrieves the current translation factor ("origin") used
+ * when displaying the child of @viewport.
+ *
+ * This function is the units-based version of
+ * gtk_clutter_viewport_get_origin().
+ *
+ * Since: 1.0
+ */
+void
+gtk_clutter_viewport_get_originu (GtkClutterViewport *viewport,
+                                  ClutterVertex      *origin)
+{
+  g_return_if_fail (GTK_IS_CLUTTER_VIEWPORT (viewport));
+
+  *origin = viewport->priv->origin;
+}
diff --git a/clutter-gtk/gtk-clutter-viewport.h b/clutter-gtk/gtk-clutter-viewport.h
new file mode 100644 (file)
index 0000000..4bd96c9
--- /dev/null
@@ -0,0 +1,89 @@
+/* gtk-clutter-viewport.h: Scrollable actor
+ *
+ * Copyright (C) 2008  Intel Corp.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * 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 see <http://www.fsf.org/licensing>.
+ *
+ * Authors:
+ *   Emmanuele Bassi  <ebassi@linux.intel.com>
+ */
+
+#if !defined(__CLUTTER_GTK_H_INSIDE__) && !defined(CLUTTER_GTK_COMPILATION)
+#error "Only <clutter-gtk/clutter-gtk.h> can be included directly."
+#endif
+
+#ifndef __GTK_CLUTTER_VIEWPORT_H__
+#define __GTK_CLUTTER_VIEWPORT_H__
+
+#include <gtk/gtk.h>
+#include <clutter/clutter.h>
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_CLUTTER_VIEWPORT               (gtk_clutter_viewport_get_type ())
+#define GTK_CLUTTER_VIEWPORT(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_CLUTTER_VIEWPORT, GtkClutterViewport))
+#define GTK_IS_CLUTTER_VIEWPORT(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_CLUTTER_VIEWPORT))
+#define GTK_CLUTTER_VIEWPORT_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_CLUTTER_VIEWPORT, GtkClutterViewportClass))
+#define GTK_IS_CLUTTER_VIEWPORT_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_CLUTTER_VIEWPORT))
+#define GTK_CLUTTER_VIEWPORT_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_CLUTTER_VIEWPORT, GtkClutterViewportClass))
+
+typedef struct _GtkClutterViewport              GtkClutterViewport;
+typedef struct _GtkClutterViewportPrivate       GtkClutterViewportPrivate;
+typedef struct _GtkClutterViewportClass         GtkClutterViewportClass;
+
+/**
+ * GtkClutterViewport:
+ *
+ * The #GtkClutterViewport structure contains only private data and
+ * should be accessed using the provided functions.
+ *
+ * Since: 0.8.2
+ */
+struct _GtkClutterViewport
+{
+  /*< private >*/
+  ClutterActor parent_instance;
+
+  GtkClutterViewportPrivate *priv;
+};
+
+/**
+ * GtkClutterViewportClass:
+ *
+ * The #GtkClutterViewportClass structure contains only private data and
+ * should be accessed using the provided functions.
+ *
+ * Since: 0.8.2
+ */
+struct _GtkClutterViewportClass
+{
+  /*< private >*/
+  ClutterActorClass parent_class;
+};
+
+GType gtk_clutter_viewport_get_type (void) G_GNUC_CONST;
+
+ClutterActor *gtk_clutter_viewport_new         (GtkAdjustment      *h_adjust,
+                                                GtkAdjustment      *v_adjust);
+
+void          gtk_clutter_viewport_get_origin  (GtkClutterViewport *viewport,
+                                                gint               *x,
+                                                gint               *y,
+                                                gint               *z);
+void          gtk_clutter_viewport_get_originu (GtkClutterViewport *viewport,
+                                                ClutterVertex      *origin);
+
+G_END_DECLS
+
+#endif /* __GTK_CLUTTER_VIEWPORT_H__ */
index f0e25a9..451b83c 100644 (file)
@@ -47,7 +47,7 @@ CFILE_GLOB=$(top_srcdir)/clutter-gtk/*.c
 
 # Header files to ignore when scanning.
 # e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h
-IGNORE_HFILES=
+IGNORE_HFILES=clutter-gtk.h
 
 # Images to copy into HTML directory.
 # e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png
index 0edd64e..c4b38d0 100644 (file)
   </chapter>
 
   <chapter>
+    <title>Clutter-Gtk Actors</title>
+    <xi:include href="xml/gtk-clutter-viewport.xml"/>
+  </chapter>
+
+  <chapter>
     <title>Miscellaneous</title>
+    <xi:include href="xml/gtk-clutter-scrollable.xml"/>
     <xi:include href="xml/gtk-clutter-util.xml"/>
   </chapter>
 
index c22095b..ee8cce9 100644 (file)
@@ -43,3 +43,42 @@ gtk_clutter_texture_set_from_pixbuf
 gtk_clutter_texture_set_from_stock
 gtk_clutter_texture_set_from_icon_name
 </SECTION>
+
+<SECTION>
+<TITLE>GtkClutterScrollable</TITLE>
+<FILE>gtk-clutter-scrollable</FILE>
+GtkClutterScrollableIface
+gtk_clutter_scrollable_set_adjustments
+gtk_clutter_scrollable_get_adjustments
+
+<SUBSECTION Standard>
+GtkClutterScrollable
+GTK_TYPE_CLUTTER_SCROLLABLE
+GTK_CLUTTER_SCROLLABLE
+GTK_IS_CLUTTER_SCROLLABLE
+GTK_CLUTTER_SCROLLABLE_GET_IFACE
+<SUBSECTION Private>
+gtk_clutter_scrollable_get_type
+</SECTION>
+
+<SECTION>
+<TITLE>GtkClutterViewport</TITLE>
+<FILE>gtk-clutter-viewport</FILE>
+GtkClutterViewport
+GtkClutterViewportClass
+gtk_clutter_viewport_new
+gtk_clutter_viewport_get_origin
+gtk_clutter_viewport_get_originu
+
+<SUBSECTION Standard>
+GTK_TYPE_CLUTTER_VIEWPORT
+GTK_CLUTTER_VIEWPORT
+GTK_IS_CLUTTER_VIEWPORT
+GTK_CLUTTER_VIEWPORT_CLASS
+GTK_IS_CLUTTER_VIEWPORT_CLASS
+GTK_CLUTTER_VIEWPORT_GET_CLASS
+
+<SUBSECTION Private>
+GtkClutterViewportPrivate
+gtk_clutter_viewport_get_type
+</SECTION>
index e2c581a..e4a1903 100644 (file)
@@ -1,3 +1,5 @@
-#include <clutter-gtk/gtk-clutter-embed.h>
+#include <clutter-gtk/clutter-gtk.h>
 
 gtk_clutter_embed_get_type
+gtk_clutter_scrollable_get_type
+gtk_clutter_viewport_get_type
index 6402291..4abe2de 100644 (file)
@@ -1,9 +1,10 @@
 NULL =
 
 noinst_PROGRAMS = \
-       gtk-clutter-test \
        gtk-clutter-events \
-       gtk-clutter-multistage
+       gtk-clutter-multistage \
+       gtk-clutter-test \
+        gtk-clutter-viewport
 
 INCLUDES = \
        -I$(srcdir) \
@@ -12,10 +13,10 @@ INCLUDES = \
 AM_CPPFLAGS = $(CLUTTER_CFLAGS) $(GTK_CFLAGS)
 
 common_deps = \
-       $(top_builddir)/clutter-gtk/libclutter-gtk-0.8.la
+       $(top_builddir)/clutter-gtk/libclutter-gtk-0.9.la
 
 common_ldadd = \
-       $(top_builddir)/clutter-gtk/libclutter-gtk-0.8.la \
+       $(top_builddir)/clutter-gtk/libclutter-gtk-0.9.la \
        $(CLUTTER_LIBS) \
        $(GTK_LIBS)
 
@@ -31,4 +32,8 @@ gtk_clutter_multistage_SOURCES = gtk-clutter-multistage.c
 gtk_clutter_multistage_DEPENDENCIES = $(common_deps)
 gtk_clutter_multistage_LDADD = $(common_ldadd)
 
+gtk_clutter_viewport_SOURCES = gtk-clutter-viewport.c
+gtk_clutter_viewport_DEPENDENCIES = $(common_deps)
+gtk_clutter_viewport_LDADD = $(common_ldadd)
+
 EXTRA_DIST = redhand.png
index 3143bc9..ec5fb9e 100644 (file)
@@ -1,8 +1,7 @@
 #include <gtk/gtk.h>
 #include <clutter/clutter.h>
 
-#include <clutter-gtk/gtk-clutter-embed.h>
-#include <clutter-gtk/gtk-clutter-util.h>
+#include <clutter-gtk/clutter-gtk.h>
 
 typedef struct {
 
index 34abe32..e97da88 100644 (file)
@@ -1,8 +1,7 @@
 #include <gtk/gtk.h>
 #include <clutter/clutter.h>
 
-#include <clutter-gtk/gtk-clutter-embed.h>
-#include <clutter-gtk/gtk-clutter-util.h>
+#include <clutter-gtk/clutter-gtk.h>
 
 int
 main (int argc, char *argv[])
index 975572f..88ab664 100644 (file)
@@ -2,8 +2,7 @@
 #include <clutter/clutter.h>
 #include <math.h>
 
-#include <clutter-gtk/gtk-clutter-embed.h>
-#include <clutter-gtk/gtk-clutter-util.h>
+#include <clutter-gtk/clutter-gtk.h>
 
 #define TRAILS 0
 #define NHANDS  2
diff --git a/examples/gtk-clutter-viewport.c b/examples/gtk-clutter-viewport.c
new file mode 100644 (file)
index 0000000..37c2980
--- /dev/null
@@ -0,0 +1,88 @@
+#include <gtk/gtk.h>
+#include <clutter/clutter.h>
+
+#include <clutter-gtk/clutter-gtk.h>
+
+int
+main (int argc, char *argv[])
+{
+  ClutterTimeline *timeline;
+  ClutterActor    *stage, *viewport, *tex;
+  ClutterColor     stage_color = { 0x61, 0x64, 0x8c, 0xff };
+  GtkWidget       *window, *embed; 
+  GtkWidget       *table, *scrollbar;
+  GtkAdjustment   *h_adjustment, *v_adjustment;
+  gint             i;
+  ClutterColor     col2 = { 0, };
+
+  if (gtk_clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
+    g_error ("Unable to initialize GtkClutter");
+
+  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
+
+  table = gtk_table_new (2, 2, FALSE);
+  gtk_container_add (GTK_CONTAINER (window), table);
+  gtk_widget_show (table);
+
+  embed = gtk_clutter_embed_new ();
+  gtk_table_attach (GTK_TABLE (table), embed,
+                    0, 1,
+                    0, 1,
+                    GTK_EXPAND | GTK_FILL,
+                    GTK_EXPAND | GTK_FILL,
+                    0, 0);
+  gtk_widget_set_size_request (embed, 320, 240);
+  gtk_widget_show (embed);
+
+  stage = gtk_clutter_embed_get_stage (GTK_CLUTTER_EMBED (embed));
+  clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
+
+  viewport = gtk_clutter_viewport_new (NULL, NULL);
+  clutter_actor_set_size (viewport, 320, 240);
+  clutter_container_add_actor (CLUTTER_CONTAINER (stage), viewport);
+
+  if (argc < 1)
+    tex = gtk_clutter_texture_new_from_stock (embed,
+                                              GTK_STOCK_DIALOG_INFO,
+                                              GTK_ICON_SIZE_DIALOG);
+  else
+    {
+      GError *error = NULL;
+
+      tex = clutter_texture_new_from_file (argv[1], &error);
+      if (error)
+        {
+          g_warning ("Unable to open `%s': %s", argv[1], error->message);
+          g_error_free (error);
+        }
+    }
+
+  clutter_container_add_actor (CLUTTER_CONTAINER (viewport), tex); 
+
+  gtk_clutter_scrollable_get_adjustments (GTK_CLUTTER_SCROLLABLE (viewport),
+                                          &h_adjustment,
+                                          &v_adjustment);
+
+  scrollbar = gtk_vscrollbar_new (v_adjustment);
+  gtk_table_attach (GTK_TABLE (table), scrollbar,
+                    1, 2,
+                    0, 1,
+                    0, GTK_EXPAND | GTK_FILL,
+                    0, 0);
+  gtk_widget_show (scrollbar);
+
+  scrollbar = gtk_hscrollbar_new (h_adjustment);
+  gtk_table_attach (GTK_TABLE (table), scrollbar,
+                    0, 1,
+                    1, 2,
+                    GTK_EXPAND | GTK_FILL, 0,
+                    0, 0);
+  gtk_widget_show (scrollbar);
+
+  gtk_widget_show (window);
+
+  gtk_main();
+
+  return 0;
+}