summaryrefslogtreecommitdiff
path: root/src/tests/clutter/interactive/test-binding-pool.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/tests/clutter/interactive/test-binding-pool.c')
-rw-r--r--src/tests/clutter/interactive/test-binding-pool.c316
1 files changed, 316 insertions, 0 deletions
diff --git a/src/tests/clutter/interactive/test-binding-pool.c b/src/tests/clutter/interactive/test-binding-pool.c
new file mode 100644
index 000000000..b33eebd42
--- /dev/null
+++ b/src/tests/clutter/interactive/test-binding-pool.c
@@ -0,0 +1,316 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <glib.h>
+#include <gmodule.h>
+
+#include <clutter/clutter.h>
+#include <clutter/clutter-keysyms.h>
+
+#define TYPE_KEY_GROUP (key_group_get_type ())
+#define KEY_GROUP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_KEY_GROUP, KeyGroup))
+#define IS_KEY_GROUP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_KEY_GROUP))
+#define KEY_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_KEY_GROUP, KeyGroupClass))
+#define IS_KEY_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_KEY_GROUP))
+
+typedef struct _KeyGroup KeyGroup;
+typedef struct _KeyGroupClass KeyGroupClass;
+
+struct _KeyGroup
+{
+ ClutterActor parent_instance;
+
+ gint selected_index;
+};
+
+struct _KeyGroupClass
+{
+ ClutterActorClass parent_class;
+
+ void (* activate) (KeyGroup *group,
+ ClutterActor *child);
+};
+
+GType key_group_get_type (void);
+
+int
+test_binding_pool_main (int argc, char *argv[]);
+
+const char *
+test_binding_pool_describe (void);
+
+G_DEFINE_TYPE (KeyGroup, key_group, CLUTTER_TYPE_ACTOR)
+
+enum
+{
+ ACTIVATE,
+
+ LAST_SIGNAL
+};
+
+static guint group_signals[LAST_SIGNAL] = { 0, };
+
+static gboolean
+key_group_action_move_left (KeyGroup *self,
+ const gchar *action_name,
+ guint key_val,
+ ClutterModifierType modifiers)
+{
+ gint n_children;
+
+ g_debug ("%s: activated '%s' (k:%d, m:%d)",
+ G_STRLOC,
+ action_name,
+ key_val,
+ modifiers);
+
+ n_children = clutter_actor_get_n_children (CLUTTER_ACTOR (self));
+
+ self->selected_index -= 1;
+
+ if (self->selected_index < 0)
+ self->selected_index = n_children - 1;
+
+ return TRUE;
+}
+
+static gboolean
+key_group_action_move_right (KeyGroup *self,
+ const gchar *action_name,
+ guint key_val,
+ ClutterModifierType modifiers)
+{
+ gint n_children;
+
+ g_debug ("%s: activated '%s' (k:%d, m:%d)",
+ G_STRLOC,
+ action_name,
+ key_val,
+ modifiers);
+
+ n_children = clutter_actor_get_n_children (CLUTTER_ACTOR (self));
+
+ self->selected_index += 1;
+
+ if (self->selected_index >= n_children)
+ self->selected_index = 0;
+
+ return TRUE;
+}
+
+static gboolean
+key_group_action_activate (KeyGroup *self,
+ const gchar *action_name,
+ guint key_val,
+ ClutterModifierType modifiers)
+{
+ ClutterActor *child = NULL;
+
+ g_debug ("%s: activated '%s' (k:%d, m:%d)",
+ G_STRLOC,
+ action_name,
+ key_val,
+ modifiers);
+
+ if (self->selected_index == -1)
+ return FALSE;
+
+ child = clutter_actor_get_child_at_index (CLUTTER_ACTOR (self),
+ self->selected_index);
+
+ if (child != NULL)
+ {
+ g_signal_emit (self, group_signals[ACTIVATE], 0, child);
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+static gboolean
+key_group_key_press (ClutterActor *actor,
+ ClutterKeyEvent *event)
+{
+ ClutterBindingPool *pool;
+ gboolean res;
+
+ pool = clutter_binding_pool_find (G_OBJECT_TYPE_NAME (actor));
+ g_assert (pool != NULL);
+
+ res = clutter_binding_pool_activate (pool,
+ event->keyval,
+ event->modifier_state,
+ G_OBJECT (actor));
+
+ /* if we activate a key binding, redraw the actor */
+ if (res)
+ clutter_actor_queue_redraw (actor);
+
+ return res ? CLUTTER_EVENT_STOP : CLUTTER_EVENT_PROPAGATE;
+}
+
+static void
+key_group_paint (ClutterActor *actor)
+{
+ KeyGroup *self = KEY_GROUP (actor);
+ ClutterActorIter iter;
+ ClutterActor *child;
+ gint i = 0;
+
+ clutter_actor_iter_init (&iter, actor);
+ while (clutter_actor_iter_next (&iter, &child))
+ {
+ /* paint the selection rectangle */
+ if (i == self->selected_index)
+ {
+ ClutterActorBox box = { 0, };
+
+ clutter_actor_get_allocation_box (child, &box);
+
+ box.x1 -= 2;
+ box.y1 -= 2;
+ box.x2 += 2;
+ box.y2 += 2;
+
+ cogl_set_source_color4ub (255, 255, 0, 224);
+ cogl_rectangle (box.x1, box.y1, box.x2, box.y2);
+ }
+
+ clutter_actor_paint (child);
+
+ i += 1;
+ }
+}
+
+static void
+key_group_class_init (KeyGroupClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
+ ClutterBindingPool *binding_pool;
+
+ actor_class->paint = key_group_paint;
+ actor_class->key_press_event = key_group_key_press;
+
+ group_signals[ACTIVATE] =
+ g_signal_new (g_intern_static_string ("activate"),
+ G_OBJECT_CLASS_TYPE (gobject_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (KeyGroupClass, activate),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ CLUTTER_TYPE_ACTOR);
+
+ binding_pool = clutter_binding_pool_get_for_class (klass);
+
+ clutter_binding_pool_install_action (binding_pool, "move-right",
+ CLUTTER_KEY_Right, 0,
+ G_CALLBACK (key_group_action_move_right),
+ NULL, NULL);
+ clutter_binding_pool_install_action (binding_pool, "move-left",
+ CLUTTER_KEY_Left, 0,
+ G_CALLBACK (key_group_action_move_left),
+ NULL, NULL);
+ clutter_binding_pool_install_action (binding_pool, "activate",
+ CLUTTER_KEY_Return, 0,
+ G_CALLBACK (key_group_action_activate),
+ NULL, NULL);
+ clutter_binding_pool_install_action (binding_pool, "activate",
+ CLUTTER_KEY_KP_Enter, 0,
+ G_CALLBACK (key_group_action_activate),
+ NULL, NULL);
+ clutter_binding_pool_install_action (binding_pool, "activate",
+ CLUTTER_KEY_ISO_Enter, 0,
+ G_CALLBACK (key_group_action_activate),
+ NULL, NULL);
+}
+
+static void
+key_group_init (KeyGroup *self)
+{
+ self->selected_index = -1;
+}
+
+static void
+on_key_group_activate (KeyGroup *group,
+ ClutterActor *child)
+{
+ g_print ("Child '%s' activated!\n", clutter_actor_get_name (child));
+}
+
+G_MODULE_EXPORT int
+test_binding_pool_main (int argc, char *argv[])
+{
+ ClutterActor *stage, *key_group;
+ gint group_x, group_y;
+
+ if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
+ return 1;
+
+ stage = clutter_stage_new ();
+ clutter_stage_set_title (CLUTTER_STAGE (stage), "Key Binding Pool");
+ g_signal_connect (stage,
+ "button-press-event", G_CALLBACK (clutter_main_quit),
+ NULL);
+ g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
+
+ key_group = g_object_new (TYPE_KEY_GROUP, NULL);
+ clutter_actor_add_child (stage, key_group);
+
+ /* add three rectangles to the key group */
+ clutter_container_add (CLUTTER_CONTAINER (key_group),
+ g_object_new (CLUTTER_TYPE_ACTOR,
+ "background-color", CLUTTER_COLOR_Red,
+ "name", "Red Rectangle",
+ "width", 100.0,
+ "height", 100.0,
+ "x", 0.0,
+ "y", 0.0,
+ NULL),
+ g_object_new (CLUTTER_TYPE_ACTOR,
+ "background-color", CLUTTER_COLOR_Green,
+ "name", "Green Rectangle",
+ "width", 100.0,
+ "height", 100.0,
+ "x", 125.0,
+ "y", 0.0,
+ NULL),
+ g_object_new (CLUTTER_TYPE_ACTOR,
+ "background-color", CLUTTER_COLOR_Blue,
+ "name", "Blue Rectangle",
+ "width", 100.0,
+ "height", 100.0,
+ "x", 250.0,
+ "y", 0.0,
+ NULL),
+ NULL);
+
+ g_signal_connect (key_group,
+ "activate", G_CALLBACK (on_key_group_activate),
+ NULL);
+
+ group_x =
+ (clutter_actor_get_width (stage) - clutter_actor_get_width (key_group))
+ / 2;
+ group_y =
+ (clutter_actor_get_height (stage) - clutter_actor_get_height (key_group))
+ / 2;
+
+ clutter_actor_set_position (key_group, group_x, group_y);
+ clutter_actor_set_reactive (key_group, TRUE);
+
+ clutter_stage_set_key_focus (CLUTTER_STAGE (stage), key_group);
+
+ clutter_actor_show (stage);
+
+ clutter_main ();
+
+ return EXIT_SUCCESS;
+}
+
+G_MODULE_EXPORT const char *
+test_binding_pool_describe (void)
+{
+ return "Binding pools example";
+}