* a #GtkClutterEmbed widget is possible to build, show and interact with
* a scene built using Clutter inside a GTK+ application.
*
- * There can be as many #GtkClutterEmbed widgets per application, but
- * they will embed and show the same #ClutterStage as a general limitation
- * of Clutter.
- *
* <note>To avoid flickering on show, you should call gtk_widget_show()
* or gtk_widget_realize() before calling clutter_actor_show() on the
* embedded #ClutterStage actor. This is needed for Clutter to be able
#include <glib-object.h>
+#include <gdk/gdk.h>
+#include <gdk/gdkx.h>
+#include <gtk/gtkmain.h>
+
#include <clutter/clutter-main.h>
#include <clutter/clutter-stage.h>
+#include <clutter/clutter-container.h>
-#include <gdk/gdk.h>
-#include <gdk/gdkx.h>
#include <clutter/clutter-x11.h>
#include "gtk-clutter-embed.h"
-G_DEFINE_TYPE (GtkClutterEmbed, gtk_clutter_embed, GTK_TYPE_WIDGET);
+static void clutter_container_iface_init (ClutterContainerIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GtkClutterEmbed,
+ gtk_clutter_embed,
+ GTK_TYPE_WIDGET,
+ G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_CONTAINER,
+ clutter_container_iface_init));
#define GTK_CLUTTER_EMBED_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GTK_TYPE_CLUTTER_EMBED, GtkClutterEmbedPrivate))
clutter_x11_set_stage_foreign (CLUTTER_STAGE (priv->stage),
GDK_WINDOW_XID (widget->window));
- clutter_redraw ();
+ clutter_redraw (CLUTTER_STAGE(priv->stage));
gtk_clutter_embed_send_configure (GTK_CLUTTER_EMBED (widget));
}
}
static void
+gtk_clutter_embed_add (ClutterContainer *container,
+ ClutterActor *actor)
+{
+ GtkClutterEmbedPrivate *priv = GTK_CLUTTER_EMBED (container)->priv;
+ ClutterContainer *stage = CLUTTER_CONTAINER (priv->stage);
+
+ clutter_container_add_actor (stage, actor);
+ g_signal_emit_by_name (container, "actor-added", actor);
+}
+
+static void
+gtk_clutter_embed_remove (ClutterContainer *container,
+ ClutterActor *actor)
+{
+ GtkClutterEmbedPrivate *priv = GTK_CLUTTER_EMBED (container)->priv;
+ ClutterContainer *stage = CLUTTER_CONTAINER (priv->stage);
+
+ g_object_ref (actor);
+
+ clutter_container_remove_actor (stage, actor);
+ g_signal_emit_by_name (container, "actor-removed", actor);
+
+ g_object_unref (actor);
+}
+
+static void
+gtk_clutter_embed_foreach (ClutterContainer *container,
+ ClutterCallback callback,
+ gpointer callback_data)
+{
+ GtkClutterEmbedPrivate *priv = GTK_CLUTTER_EMBED (container)->priv;
+ ClutterContainer *stage = CLUTTER_CONTAINER (priv->stage);
+
+ clutter_container_foreach (stage, callback, callback_data);
+}
+
+static void
+gtk_clutter_embed_raise (ClutterContainer *container,
+ ClutterActor *child,
+ ClutterActor *sibling)
+{
+ GtkClutterEmbedPrivate *priv = GTK_CLUTTER_EMBED (container)->priv;
+ ClutterContainer *stage = CLUTTER_CONTAINER (priv->stage);
+
+ clutter_container_raise_child (stage, child, sibling);
+}
+
+static void
+gtk_clutter_embed_lower (ClutterContainer *container,
+ ClutterActor *child,
+ ClutterActor *sibling)
+{
+ GtkClutterEmbedPrivate *priv = GTK_CLUTTER_EMBED (container)->priv;
+ ClutterContainer *stage = CLUTTER_CONTAINER (priv->stage);
+
+ clutter_container_lower_child (stage, child, sibling);
+}
+
+static void
+gtk_clutter_embed_sort_depth_order (ClutterContainer *container)
+{
+ GtkClutterEmbedPrivate *priv = GTK_CLUTTER_EMBED (container)->priv;
+ ClutterContainer *stage = CLUTTER_CONTAINER (priv->stage);
+
+ clutter_container_sort_depth_order (stage);
+}
+
+static void
+clutter_container_iface_init (ClutterContainerIface *iface)
+{
+ iface->add = gtk_clutter_embed_add;
+ iface->remove = gtk_clutter_embed_remove;
+ iface->foreach = gtk_clutter_embed_foreach;
+ iface->raise = gtk_clutter_embed_raise;
+ iface->lower = gtk_clutter_embed_lower;
+ iface->sort_depth_order = gtk_clutter_embed_sort_depth_order;
+}
+
+static void
gtk_clutter_embed_class_init (GtkClutterEmbedClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gtk_widget_set_double_buffered (GTK_WIDGET (embed), FALSE);
/* note we never ref or unref this */
- priv->stage = clutter_stage_get_default ();
+ priv->stage = clutter_stage_new ();
+ /* we always create new stages rather than use the default */
+ /* priv->stage = clutter_stage_get_default (); */
/* We need to use the colormap from the Clutter visual */
xvinfo = clutter_x11_get_stage_visual (CLUTTER_STAGE (priv->stage));
/**
* gtk_clutter_init:
*
- * This function should be called instead of #clutter_init() and after
- * #gtk_init()
+ * This function should be called instead of clutter_init() and
+ * gtk_init().
*
* Return value: %CLUTTER_INIT_SUCCESS on success, a negative integer
* on failure.
ClutterInitError
gtk_clutter_init (int *argc, char ***argv)
{
- clutter_x11_set_display (GDK_DISPLAY());
- clutter_x11_disable_event_retrieval ();
+ if (!gtk_init_check (argc, argv))
+ return CLUTTER_INIT_ERROR_GTK;
- /* FIXME: call gtk_init() here? */
+ clutter_x11_set_display (GDK_DISPLAY ());
+ clutter_x11_disable_event_retrieval ();
return clutter_init (argc, argv);
}