~ubuntu-branches/ubuntu/vivid/clutter-1.0/vivid-proposed

« back to all changes in this revision

Viewing changes to tests/conform/binding-pool.c

  • Committer: Package Import Robot
  • Author(s): Michael Biebl
  • Date: 2012-05-01 23:50:39 UTC
  • mfrom: (4.1.22 experimental)
  • Revision ID: package-import@ubuntu.com-20120501235039-7wehcmtr33nqhv67
Tags: 1.10.4-2
Upload to unstable

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <string.h>
 
2
 
 
3
#include <glib.h>
 
4
 
 
5
#include <clutter/clutter.h>
 
6
#include <clutter/clutter-keysyms.h>
 
7
 
 
8
#include "test-conform-common.h"
 
9
 
 
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))
 
15
 
 
16
typedef struct _KeyGroup        KeyGroup;
 
17
typedef struct _KeyGroupClass   KeyGroupClass;
 
18
 
 
19
struct _KeyGroup
 
20
{
 
21
  ClutterGroup parent_instance;
 
22
 
 
23
  gint selected_index;
 
24
};
 
25
 
 
26
struct _KeyGroupClass
 
27
{
 
28
  ClutterGroupClass parent_class;
 
29
 
 
30
  void (* activate) (KeyGroup     *group,
 
31
                     ClutterActor *child);
 
32
};
 
33
 
 
34
G_DEFINE_TYPE (KeyGroup, key_group, CLUTTER_TYPE_GROUP);
 
35
 
 
36
enum
 
37
{
 
38
  ACTIVATE,
 
39
 
 
40
  LAST_SIGNAL
 
41
};
 
42
 
 
43
static guint group_signals[LAST_SIGNAL] = { 0, };
 
44
 
 
45
static gboolean
 
46
key_group_action_move_left (KeyGroup            *self,
 
47
                            const gchar         *action_name,
 
48
                            guint                key_val,
 
49
                            ClutterModifierType  modifiers)
 
50
{
 
51
  gint n_children;
 
52
 
 
53
  g_assert_cmpstr (action_name, ==, "move-left");
 
54
  g_assert_cmpint (key_val, ==, CLUTTER_KEY_Left);
 
55
 
 
56
  n_children = clutter_group_get_n_children (CLUTTER_GROUP (self));
 
57
 
 
58
  self->selected_index -= 1;
 
59
 
 
60
  if (self->selected_index < 0)
 
61
    self->selected_index = n_children - 1;
 
62
 
 
63
  return TRUE;
 
64
}
 
65
 
 
66
static gboolean
 
67
key_group_action_move_right (KeyGroup            *self,
 
68
                             const gchar         *action_name,
 
69
                             guint                key_val,
 
70
                             ClutterModifierType  modifiers)
 
71
{
 
72
  gint n_children;
 
73
 
 
74
  g_assert_cmpstr (action_name, ==, "move-right");
 
75
  g_assert_cmpint (key_val, ==, CLUTTER_KEY_Right);
 
76
 
 
77
  n_children = clutter_group_get_n_children (CLUTTER_GROUP (self));
 
78
 
 
79
  self->selected_index += 1;
 
80
 
 
81
  if (self->selected_index >= n_children)
 
82
    self->selected_index = 0;
 
83
 
 
84
  return TRUE;
 
85
}
 
86
 
 
87
static gboolean
 
88
key_group_action_activate (KeyGroup            *self,
 
89
                           const gchar         *action_name,
 
90
                           guint                key_val,
 
91
                           ClutterModifierType  modifiers)
 
92
{
 
93
  ClutterActor *child = NULL;
 
94
 
 
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);
 
99
 
 
100
  if (self->selected_index == -1)
 
101
    return FALSE;
 
102
 
 
103
  child = clutter_group_get_nth_child (CLUTTER_GROUP (self),
 
104
                                       self->selected_index);
 
105
 
 
106
  if (child)
 
107
    {
 
108
      g_signal_emit (self, group_signals[ACTIVATE], 0, child);
 
109
      return TRUE;
 
110
    }
 
111
  else
 
112
    return FALSE;
 
113
}
 
114
 
 
115
static gboolean
 
116
key_group_key_press (ClutterActor    *actor,
 
117
                     ClutterKeyEvent *event)
 
118
{
 
119
  ClutterBindingPool *pool;
 
120
  gboolean res;
 
121
 
 
122
  pool = clutter_binding_pool_find (G_OBJECT_TYPE_NAME (actor));
 
123
  g_assert (pool != NULL);
 
124
 
 
125
  res = clutter_binding_pool_activate (pool,
 
126
                                       event->keyval,
 
127
                                       event->modifier_state,
 
128
                                       G_OBJECT (actor));
 
129
 
 
130
  /* if we activate a key binding, redraw the actor */
 
131
  if (res)
 
132
    clutter_actor_queue_redraw (actor);
 
133
 
 
134
  return res;
 
135
}
 
136
 
 
137
static void
 
138
key_group_paint (ClutterActor *actor)
 
139
{
 
140
  KeyGroup *self = KEY_GROUP (actor);
 
141
  GList *children, *l;
 
142
  gint i;
 
143
 
 
144
  children = clutter_container_get_children (CLUTTER_CONTAINER (self));
 
145
 
 
146
  for (l = children, i = 0; l != NULL; l = l->next, i++)
 
147
    {
 
148
      ClutterActor *child = l->data;
 
149
 
 
150
      /* paint the selection rectangle */
 
151
      if (i == self->selected_index)
 
152
        {
 
153
          ClutterActorBox box = { 0, };
 
154
 
 
155
          clutter_actor_get_allocation_box (child, &box);
 
156
 
 
157
          box.x1 -= 2;
 
158
          box.y1 -= 2;
 
159
          box.x2 += 2;
 
160
          box.y2 += 2;
 
161
 
 
162
          cogl_set_source_color4ub (255, 255, 0, 224);
 
163
          cogl_rectangle (box.x1, box.y1, box.x2, box.y2);
 
164
        }
 
165
 
 
166
      clutter_actor_paint (child);
 
167
    }
 
168
 
 
169
  g_list_free (children);
 
170
}
 
171
 
 
172
static void
 
173
key_group_finalize (GObject *gobject)
 
174
{
 
175
  G_OBJECT_CLASS (key_group_parent_class)->finalize (gobject);
 
176
}
 
177
 
 
178
static void
 
179
key_group_class_init (KeyGroupClass *klass)
 
180
{
 
181
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 
182
  ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
 
183
  ClutterBindingPool *binding_pool;
 
184
 
 
185
  gobject_class->finalize = key_group_finalize;
 
186
 
 
187
  actor_class->paint = key_group_paint;
 
188
  actor_class->key_press_event = key_group_key_press;
 
189
 
 
190
  group_signals[ACTIVATE] =
 
191
    g_signal_new (g_intern_static_string ("activate"),
 
192
                  G_OBJECT_CLASS_TYPE (gobject_class),
 
193
                  G_SIGNAL_RUN_LAST,
 
194
                  G_STRUCT_OFFSET (KeyGroupClass, activate),
 
195
                  NULL, NULL,
 
196
                  g_cclosure_marshal_VOID__OBJECT,
 
197
                  G_TYPE_NONE, 1,
 
198
                  CLUTTER_TYPE_ACTOR);
 
199
 
 
200
  binding_pool = clutter_binding_pool_get_for_class (klass);
 
201
 
 
202
  clutter_binding_pool_install_action (binding_pool, "move-right",
 
203
                                       CLUTTER_KEY_Right, 0,
 
204
                                       G_CALLBACK (key_group_action_move_right),
 
205
                                       NULL, NULL);
 
206
  clutter_binding_pool_install_action (binding_pool, "move-left",
 
207
                                       CLUTTER_KEY_Left, 0,
 
208
                                       G_CALLBACK (key_group_action_move_left),
 
209
                                       NULL, NULL);
 
210
  clutter_binding_pool_install_action (binding_pool, "activate",
 
211
                                       CLUTTER_KEY_Return, 0,
 
212
                                       G_CALLBACK (key_group_action_activate),
 
213
                                       NULL, NULL);
 
214
  clutter_binding_pool_install_action (binding_pool, "activate",
 
215
                                       CLUTTER_KEY_KP_Enter, 0,
 
216
                                       G_CALLBACK (key_group_action_activate),
 
217
                                       NULL, NULL);
 
218
  clutter_binding_pool_install_action (binding_pool, "activate",
 
219
                                       CLUTTER_KEY_ISO_Enter, 0,
 
220
                                       G_CALLBACK (key_group_action_activate),
 
221
                                       NULL, NULL);
 
222
}
 
223
 
 
224
static void
 
225
key_group_init (KeyGroup *self)
 
226
{
 
227
  self->selected_index = -1;
 
228
}
 
229
 
 
230
static void
 
231
init_event (ClutterKeyEvent *event)
 
232
{
 
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 */
 
240
}
 
241
 
 
242
static void
 
243
send_keyval (KeyGroup *group, int keyval)
 
244
{
 
245
  ClutterKeyEvent event;
 
246
 
 
247
  init_event (&event);
 
248
  event.keyval = keyval;
 
249
  event.unicode_value = 0; /* should be ignored for cursor keys etc. */
 
250
 
 
251
  clutter_actor_event (CLUTTER_ACTOR (group), (ClutterEvent *) &event, FALSE);
 
252
}
 
253
 
 
254
static void
 
255
on_activate (KeyGroup     *key_group,
 
256
             ClutterActor *child,
 
257
             gpointer      data)
 
258
{
 
259
  gint _index = GPOINTER_TO_INT (data);
 
260
 
 
261
  g_assert_cmpint (key_group->selected_index, ==, _index);
 
262
}
 
263
 
 
264
void
 
265
binding_pool (TestConformSimpleFixture *fixture,
 
266
              gconstpointer             data)
 
267
{
 
268
  KeyGroup *key_group = g_object_new (TYPE_KEY_GROUP, NULL);
 
269
 
 
270
  clutter_container_add (CLUTTER_CONTAINER (key_group),
 
271
                         g_object_new (CLUTTER_TYPE_RECTANGLE,
 
272
                                       "width", 50.0,
 
273
                                       "height", 50.0,
 
274
                                       "x", 0.0, "y", 0.0,
 
275
                                       NULL),
 
276
                         g_object_new (CLUTTER_TYPE_RECTANGLE,
 
277
                                       "width", 50.0,
 
278
                                       "height", 50.0,
 
279
                                       "x", 75.0, "y", 0.0,
 
280
                                       NULL),
 
281
                         g_object_new (CLUTTER_TYPE_RECTANGLE,
 
282
                                       "width", 50.0,
 
283
                                       "height", 50.0,
 
284
                                       "x", 150.0, "y", 0.0,
 
285
                                       NULL),
 
286
                         NULL);
 
287
 
 
288
  g_assert_cmpint (key_group->selected_index, ==, -1);
 
289
 
 
290
  send_keyval (key_group, CLUTTER_KEY_Left);
 
291
  g_assert_cmpint (key_group->selected_index, ==, 2);
 
292
 
 
293
  send_keyval (key_group, CLUTTER_KEY_Left);
 
294
  g_assert_cmpint (key_group->selected_index, ==, 1);
 
295
 
 
296
  send_keyval (key_group, CLUTTER_KEY_Right);
 
297
  g_assert_cmpint (key_group->selected_index, ==, 2);
 
298
 
 
299
  send_keyval (key_group, CLUTTER_KEY_Right);
 
300
  g_assert_cmpint (key_group->selected_index, ==, 0);
 
301
 
 
302
  g_signal_connect (key_group,
 
303
                    "activate", G_CALLBACK (on_activate),
 
304
                    GINT_TO_POINTER (0));
 
305
 
 
306
  send_keyval (key_group, CLUTTER_KEY_Return);
 
307
 
 
308
  clutter_actor_destroy (CLUTTER_ACTOR (key_group));
 
309
}