5
#include <clutter/clutter.h>
6
#include <clutter/clutter-keysyms.h>
8
#include "test-conform-common.h"
10
#define TYPE_KEY_GROUP (key_group_get_type ())
11
#define KEY_GROUP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_KEY_GROUP, KeyGroup))
12
#define IS_KEY_GROUP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_KEY_GROUP))
13
#define KEY_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_KEY_GROUP, KeyGroupClass))
14
#define IS_KEY_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_KEY_GROUP))
16
typedef struct _KeyGroup KeyGroup;
17
typedef struct _KeyGroupClass KeyGroupClass;
21
ClutterGroup parent_instance;
28
ClutterGroupClass parent_class;
30
void (* activate) (KeyGroup *group,
34
G_DEFINE_TYPE (KeyGroup, key_group, CLUTTER_TYPE_GROUP);
43
static guint group_signals[LAST_SIGNAL] = { 0, };
46
key_group_action_move_left (KeyGroup *self,
47
const gchar *action_name,
49
ClutterModifierType modifiers)
53
g_assert_cmpstr (action_name, ==, "move-left");
54
g_assert_cmpint (key_val, ==, CLUTTER_KEY_Left);
56
n_children = clutter_group_get_n_children (CLUTTER_GROUP (self));
58
self->selected_index -= 1;
60
if (self->selected_index < 0)
61
self->selected_index = n_children - 1;
67
key_group_action_move_right (KeyGroup *self,
68
const gchar *action_name,
70
ClutterModifierType modifiers)
74
g_assert_cmpstr (action_name, ==, "move-right");
75
g_assert_cmpint (key_val, ==, CLUTTER_KEY_Right);
77
n_children = clutter_group_get_n_children (CLUTTER_GROUP (self));
79
self->selected_index += 1;
81
if (self->selected_index >= n_children)
82
self->selected_index = 0;
88
key_group_action_activate (KeyGroup *self,
89
const gchar *action_name,
91
ClutterModifierType modifiers)
93
ClutterActor *child = NULL;
95
g_assert_cmpstr (action_name, ==, "activate");
96
g_assert (key_val == CLUTTER_KEY_Return ||
97
key_val == CLUTTER_KEY_KP_Enter ||
98
key_val == CLUTTER_KEY_ISO_Enter);
100
if (self->selected_index == -1)
103
child = clutter_group_get_nth_child (CLUTTER_GROUP (self),
104
self->selected_index);
108
g_signal_emit (self, group_signals[ACTIVATE], 0, child);
116
key_group_key_press (ClutterActor *actor,
117
ClutterKeyEvent *event)
119
ClutterBindingPool *pool;
122
pool = clutter_binding_pool_find (G_OBJECT_TYPE_NAME (actor));
123
g_assert (pool != NULL);
125
res = clutter_binding_pool_activate (pool,
127
event->modifier_state,
130
/* if we activate a key binding, redraw the actor */
132
clutter_actor_queue_redraw (actor);
138
key_group_paint (ClutterActor *actor)
140
KeyGroup *self = KEY_GROUP (actor);
144
children = clutter_container_get_children (CLUTTER_CONTAINER (self));
146
for (l = children, i = 0; l != NULL; l = l->next, i++)
148
ClutterActor *child = l->data;
150
/* paint the selection rectangle */
151
if (i == self->selected_index)
153
ClutterActorBox box = { 0, };
155
clutter_actor_get_allocation_box (child, &box);
162
cogl_set_source_color4ub (255, 255, 0, 224);
163
cogl_rectangle (box.x1, box.y1, box.x2, box.y2);
166
clutter_actor_paint (child);
169
g_list_free (children);
173
key_group_finalize (GObject *gobject)
175
G_OBJECT_CLASS (key_group_parent_class)->finalize (gobject);
179
key_group_class_init (KeyGroupClass *klass)
181
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
182
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
183
ClutterBindingPool *binding_pool;
185
gobject_class->finalize = key_group_finalize;
187
actor_class->paint = key_group_paint;
188
actor_class->key_press_event = key_group_key_press;
190
group_signals[ACTIVATE] =
191
g_signal_new (g_intern_static_string ("activate"),
192
G_OBJECT_CLASS_TYPE (gobject_class),
194
G_STRUCT_OFFSET (KeyGroupClass, activate),
196
g_cclosure_marshal_VOID__OBJECT,
200
binding_pool = clutter_binding_pool_get_for_class (klass);
202
clutter_binding_pool_install_action (binding_pool, "move-right",
203
CLUTTER_KEY_Right, 0,
204
G_CALLBACK (key_group_action_move_right),
206
clutter_binding_pool_install_action (binding_pool, "move-left",
208
G_CALLBACK (key_group_action_move_left),
210
clutter_binding_pool_install_action (binding_pool, "activate",
211
CLUTTER_KEY_Return, 0,
212
G_CALLBACK (key_group_action_activate),
214
clutter_binding_pool_install_action (binding_pool, "activate",
215
CLUTTER_KEY_KP_Enter, 0,
216
G_CALLBACK (key_group_action_activate),
218
clutter_binding_pool_install_action (binding_pool, "activate",
219
CLUTTER_KEY_ISO_Enter, 0,
220
G_CALLBACK (key_group_action_activate),
225
key_group_init (KeyGroup *self)
227
self->selected_index = -1;
231
init_event (ClutterKeyEvent *event)
233
event->type = CLUTTER_KEY_PRESS;
234
event->time = 0; /* not needed */
235
event->flags = CLUTTER_EVENT_FLAG_SYNTHETIC;
236
event->stage = NULL; /* not needed */
237
event->source = NULL; /* not needed */
238
event->modifier_state = 0;
239
event->hardware_keycode = 0; /* not needed */
243
send_keyval (KeyGroup *group, int keyval)
245
ClutterKeyEvent event;
248
event.keyval = keyval;
249
event.unicode_value = 0; /* should be ignored for cursor keys etc. */
251
clutter_actor_event (CLUTTER_ACTOR (group), (ClutterEvent *) &event, FALSE);
255
on_activate (KeyGroup *key_group,
259
gint _index = GPOINTER_TO_INT (data);
261
g_assert_cmpint (key_group->selected_index, ==, _index);
265
binding_pool (TestConformSimpleFixture *fixture,
268
KeyGroup *key_group = g_object_new (TYPE_KEY_GROUP, NULL);
270
clutter_container_add (CLUTTER_CONTAINER (key_group),
271
g_object_new (CLUTTER_TYPE_RECTANGLE,
276
g_object_new (CLUTTER_TYPE_RECTANGLE,
281
g_object_new (CLUTTER_TYPE_RECTANGLE,
284
"x", 150.0, "y", 0.0,
288
g_assert_cmpint (key_group->selected_index, ==, -1);
290
send_keyval (key_group, CLUTTER_KEY_Left);
291
g_assert_cmpint (key_group->selected_index, ==, 2);
293
send_keyval (key_group, CLUTTER_KEY_Left);
294
g_assert_cmpint (key_group->selected_index, ==, 1);
296
send_keyval (key_group, CLUTTER_KEY_Right);
297
g_assert_cmpint (key_group->selected_index, ==, 2);
299
send_keyval (key_group, CLUTTER_KEY_Right);
300
g_assert_cmpint (key_group->selected_index, ==, 0);
302
g_signal_connect (key_group,
303
"activate", G_CALLBACK (on_activate),
304
GINT_TO_POINTER (0));
306
send_keyval (key_group, CLUTTER_KEY_Return);
308
clutter_actor_destroy (CLUTTER_ACTOR (key_group));