diff options
Diffstat (limited to '')
-rw-r--r-- | libraries/evas/src/examples/evas-events.c | 413 |
1 files changed, 413 insertions, 0 deletions
diff --git a/libraries/evas/src/examples/evas-events.c b/libraries/evas/src/examples/evas-events.c new file mode 100644 index 0000000..28b22ed --- /dev/null +++ b/libraries/evas/src/examples/evas-events.c | |||
@@ -0,0 +1,413 @@ | |||
1 | /** | ||
2 | * Simple Evas example illustrating how to interact with canvas' (and | ||
3 | * its objects') events and other canvas operations. | ||
4 | * | ||
5 | * You'll need at least one engine built for it (excluding the buffer | ||
6 | * one) and the png image loader also built. See stdout/stderr for | ||
7 | * output. | ||
8 | * | ||
9 | * @verbatim | ||
10 | * gcc -o evas-events evas-events.c `pkg-config --libs --cflags evas ecore ecore-evas` | ||
11 | * @endverbatim | ||
12 | */ | ||
13 | |||
14 | #ifdef HAVE_CONFIG_H | ||
15 | |||
16 | #include "config.h" | ||
17 | #else | ||
18 | |||
19 | #define PACKAGE_EXAMPLES_DIR "." | ||
20 | #define __UNUSED__ | ||
21 | |||
22 | #endif | ||
23 | |||
24 | #include <Ecore.h> | ||
25 | #include <Ecore_Evas.h> | ||
26 | #include <stdio.h> | ||
27 | #include <errno.h> | ||
28 | |||
29 | #define WIDTH (320) | ||
30 | #define HEIGHT (240) | ||
31 | |||
32 | static const char *img_path = PACKAGE_EXAMPLES_DIR "/enlightenment.png"; | ||
33 | |||
34 | static const char *commands = \ | ||
35 | "commands are:\n" | ||
36 | "\ta - toggle animation timer\n" | ||
37 | "\tc - cycle between focus and key grabs for key input\n" | ||
38 | "\td - delete canvas callbacks\n" | ||
39 | "\tf - freeze input for 3 seconds\n" | ||
40 | "\tp - toggle precise point collision detection on image\n" | ||
41 | "\tControl + o - add an obscured rectangle\n" | ||
42 | "\th - print help\n"; | ||
43 | |||
44 | struct test_data | ||
45 | { | ||
46 | Ecore_Evas *ee; | ||
47 | Evas *canvas; | ||
48 | Evas_Object *img, *bg; | ||
49 | Ecore_Timer *resize_timer, *freeze_timer; | ||
50 | Eina_Bool obscured, focus; | ||
51 | }; | ||
52 | |||
53 | static struct test_data d = {0}; | ||
54 | |||
55 | /* here to keep our example's window size and background image's | ||
56 | * size in synchrony */ | ||
57 | static void | ||
58 | _canvas_resize_cb(Ecore_Evas *ee) | ||
59 | { | ||
60 | int w, h; | ||
61 | |||
62 | ecore_evas_geometry_get(ee, NULL, NULL, &w, &h); | ||
63 | evas_object_resize(d.bg, w, h); | ||
64 | } | ||
65 | |||
66 | /* called when our rectangle gets focus */ | ||
67 | static void | ||
68 | _object_focus_in_cb(void *data __UNUSED__, | ||
69 | Evas *e, | ||
70 | void *event_info) | ||
71 | { | ||
72 | fprintf(stdout, "An object got focused: %s\n", | ||
73 | evas_object_name_get(event_info)); | ||
74 | |||
75 | fprintf(stdout, "Let's recheck it: %s\n", | ||
76 | evas_object_name_get(evas_focus_get(e))); | ||
77 | |||
78 | fprintf(stdout, "And again: %s\n", evas_object_focus_get(event_info) ? | ||
79 | "OK!" : "Oops, something is bad."); | ||
80 | } | ||
81 | |||
82 | /* render flush callback */ | ||
83 | static void | ||
84 | _render_flush_cb(void *data __UNUSED__, | ||
85 | Evas *e __UNUSED__, | ||
86 | void *event_info __UNUSED__) | ||
87 | { | ||
88 | fprintf(stdout, "Canvas is about to flush its rendering pipeline!\n"); | ||
89 | } | ||
90 | |||
91 | /* put some action in the canvas */ | ||
92 | static Eina_Bool | ||
93 | _resize_cb(void *data __UNUSED__) | ||
94 | { | ||
95 | int w, h, cw, ch; | ||
96 | |||
97 | evas_object_geometry_get(d.img, NULL, NULL, &w, &h); | ||
98 | ecore_evas_geometry_get(d.ee, NULL, NULL, &cw, &ch); | ||
99 | |||
100 | if (w < cw) | ||
101 | evas_object_resize(d.img, cw, ch); | ||
102 | else | ||
103 | evas_object_resize(d.img, cw / 2, ch / 2); | ||
104 | |||
105 | return EINA_TRUE; /* re-issue the timer */ | ||
106 | } | ||
107 | |||
108 | /* let's have our events back */ | ||
109 | static Eina_Bool | ||
110 | _thaw_cb(void *data __UNUSED__) | ||
111 | { | ||
112 | fprintf(stdout, "Canvas was frozen %d times, now thawing.\n", | ||
113 | evas_event_freeze_get(d.canvas)); | ||
114 | evas_event_thaw(d.canvas); | ||
115 | return EINA_FALSE; /* do not re-issue the timer */ | ||
116 | } | ||
117 | |||
118 | /* mouse enters the object's area */ | ||
119 | static void | ||
120 | _on_mouse_in(void *data __UNUSED__, | ||
121 | Evas *evas __UNUSED__, | ||
122 | Evas_Object *o __UNUSED__, | ||
123 | void *einfo __UNUSED__) | ||
124 | { | ||
125 | fprintf(stdout, "Enlightenment logo has had the mouse in.\n"); | ||
126 | } | ||
127 | |||
128 | static void | ||
129 | _on_mouse_out(void *data __UNUSED__, | ||
130 | Evas *evas __UNUSED__, | ||
131 | Evas_Object *o __UNUSED__, | ||
132 | void *einfo __UNUSED__) | ||
133 | { | ||
134 | fprintf(stdout, "Enlightenment logo has had the mouse out.\n"); | ||
135 | } /* mouse exits the object's area */ | ||
136 | |||
137 | /* examine the keys pressed */ | ||
138 | static void | ||
139 | _on_keydown(void *data __UNUSED__, | ||
140 | Evas *evas, | ||
141 | Evas_Object *o __UNUSED__, | ||
142 | void *einfo) | ||
143 | { | ||
144 | const Evas_Modifier *mods; | ||
145 | Evas_Event_Key_Down *ev = einfo; | ||
146 | |||
147 | fprintf(stdout, "We've got key input: %s\n", ev->keyname); | ||
148 | fprintf(stdout, "It actually came from %s\n", d.focus ? | ||
149 | "focus" : "key grab"); | ||
150 | |||
151 | if (strcmp(ev->keyname, "h") == 0) /* print help */ | ||
152 | { | ||
153 | fprintf(stdout, commands); | ||
154 | return; | ||
155 | } | ||
156 | |||
157 | if (strcmp(ev->keyname, "a") == 0) /* toggle animation timer */ | ||
158 | { | ||
159 | if (d.resize_timer != NULL) | ||
160 | { | ||
161 | fprintf(stdout, "Stopping animation timer\n"); | ||
162 | ecore_timer_del(d.resize_timer); | ||
163 | d.resize_timer = NULL; | ||
164 | } | ||
165 | else | ||
166 | { | ||
167 | fprintf(stdout, "Re-issuing animation timer\n"); | ||
168 | d.resize_timer = ecore_timer_add(2, _resize_cb, NULL); | ||
169 | } | ||
170 | return; | ||
171 | } | ||
172 | |||
173 | if (strcmp(ev->keyname, "c") == 0) /* cycle between focus and key | ||
174 | * grabs for key input */ | ||
175 | { | ||
176 | Eina_Bool ret; | ||
177 | Evas_Modifier_Mask mask = | ||
178 | evas_key_modifier_mask_get(d.canvas, "Control"); | ||
179 | |||
180 | fprintf(stdout, "Switching to %s for key input\n", d.focus ? | ||
181 | "key grabs" : "focus"); | ||
182 | |||
183 | if (d.focus) | ||
184 | { | ||
185 | evas_object_focus_set(d.bg, EINA_FALSE); | ||
186 | fprintf(stdout, "Focused object is now %s\n", | ||
187 | evas_focus_get(d.canvas) ? | ||
188 | "still valid! Something went wrong." : "none."); | ||
189 | |||
190 | ret = evas_object_key_grab(d.bg, "a", 0, 0, EINA_TRUE); | ||
191 | if (!ret) | ||
192 | { | ||
193 | fprintf(stdout, "Something went wrong with key grabs.\n"); | ||
194 | goto c_end; | ||
195 | } | ||
196 | ret = evas_object_key_grab(d.bg, "c", 0, 0, EINA_TRUE); | ||
197 | if (!ret) | ||
198 | { | ||
199 | fprintf(stdout, "Something went wrong with key grabs.\n"); | ||
200 | goto c_end; | ||
201 | } | ||
202 | ret = evas_object_key_grab(d.bg, "d", 0, 0, EINA_TRUE); | ||
203 | if (!ret) | ||
204 | { | ||
205 | fprintf(stdout, "Something went wrong with key grabs.\n"); | ||
206 | goto c_end; | ||
207 | } | ||
208 | ret = evas_object_key_grab(d.bg, "f", 0, 0, EINA_TRUE); | ||
209 | if (!ret) | ||
210 | { | ||
211 | fprintf(stdout, "Something went wrong with key grabs.\n"); | ||
212 | goto c_end; | ||
213 | } | ||
214 | ret = evas_object_key_grab(d.bg, "p", 0, 0, EINA_TRUE); | ||
215 | if (!ret) | ||
216 | { | ||
217 | fprintf(stdout, "Something went wrong with key grabs.\n"); | ||
218 | goto c_end; | ||
219 | } | ||
220 | ret = evas_object_key_grab(d.bg, "o", mask, 0, EINA_TRUE); | ||
221 | if (!ret) | ||
222 | { | ||
223 | fprintf(stdout, "Something went wrong with key grabs.\n"); | ||
224 | goto c_end; | ||
225 | } | ||
226 | ret = evas_object_key_grab(d.bg, "h", 0, 0, EINA_TRUE); | ||
227 | if (!ret) | ||
228 | { | ||
229 | fprintf(stdout, "Something went wrong with key grabs.\n"); | ||
230 | goto c_end; | ||
231 | } | ||
232 | } | ||
233 | else /* got here by key grabs */ | ||
234 | { | ||
235 | evas_object_key_ungrab(d.bg, "a", 0, 0); | ||
236 | evas_object_key_ungrab(d.bg, "c", 0, 0); | ||
237 | evas_object_key_ungrab(d.bg, "d", 0, 0); | ||
238 | evas_object_key_ungrab(d.bg, "f", 0, 0); | ||
239 | evas_object_key_ungrab(d.bg, "p", 0, 0); | ||
240 | evas_object_key_ungrab(d.bg, "o", mask, 0); | ||
241 | evas_object_key_ungrab(d.bg, "h", 0, 0); | ||
242 | |||
243 | evas_object_focus_set(d.bg, EINA_TRUE); | ||
244 | } | ||
245 | |||
246 | c_end: | ||
247 | d.focus = !d.focus; | ||
248 | |||
249 | return; | ||
250 | } | ||
251 | |||
252 | if (strcmp(ev->keyname, "d") == 0) /* delete canvas' callbacks */ | ||
253 | { | ||
254 | fprintf(stdout, "Deleting canvas event callbacks\n"); | ||
255 | evas_event_callback_del_full(evas, EVAS_CALLBACK_RENDER_FLUSH_PRE, | ||
256 | _render_flush_cb, NULL); | ||
257 | evas_event_callback_del_full( | ||
258 | evas, EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_IN, | ||
259 | _object_focus_in_cb, NULL); | ||
260 | return; | ||
261 | } | ||
262 | |||
263 | if (strcmp(ev->keyname, "f") == 0) /* freeze input for 3 seconds */ | ||
264 | { | ||
265 | fprintf(stdout, "Freezing input for 3 seconds\n"); | ||
266 | evas_event_freeze(evas); | ||
267 | d.freeze_timer = ecore_timer_add(3, _thaw_cb, NULL); | ||
268 | return; | ||
269 | } | ||
270 | |||
271 | if (strcmp(ev->keyname, "p") == 0) /* toggle precise point | ||
272 | * collision detection */ | ||
273 | { | ||
274 | Eina_Bool precise = evas_object_precise_is_inside_get(d.img); | ||
275 | |||
276 | fprintf(stdout, "Toggling precise point collision detection %s on" | ||
277 | " Enlightenment logo\n", precise ? "off" : "on"); | ||
278 | evas_object_precise_is_inside_set(d.img, !precise); | ||
279 | |||
280 | return; | ||
281 | } | ||
282 | |||
283 | mods = evas_key_modifier_get(evas); | ||
284 | if (evas_key_modifier_is_set(mods, "Control") && | ||
285 | (strcmp(ev->keyname, "o") == 0)) /* add an obscured | ||
286 | * rectangle to the middle | ||
287 | * of the canvas */ | ||
288 | { | ||
289 | fprintf(stdout, "Toggling obscured rectangle on canvas\n"); | ||
290 | if (!d.obscured) | ||
291 | { | ||
292 | int w, h; | ||
293 | evas_output_viewport_get(evas, NULL, NULL, &w, &h); | ||
294 | evas_obscured_rectangle_add(evas, w / 4, h / 4, w / 2, h / 2); | ||
295 | } | ||
296 | else | ||
297 | { | ||
298 | int w, h; | ||
299 | Eina_Rectangle *rect; | ||
300 | Eina_List *updates, *l; | ||
301 | |||
302 | evas_output_viewport_get(evas, NULL, NULL, &w, &h); | ||
303 | evas_obscured_clear(evas); | ||
304 | |||
305 | /* we have to flag a damage region here because | ||
306 | * evas_obscured_clear() doesn't change the canvas' | ||
307 | * state. we'd have to wait for an animation step, for | ||
308 | * example, to get the result, without it */ | ||
309 | evas_damage_rectangle_add(evas, 0, 0, w, h); | ||
310 | |||
311 | updates = evas_render_updates(evas); | ||
312 | |||
313 | EINA_LIST_FOREACH(updates, l, rect) | ||
314 | { | ||
315 | fprintf(stdout, "Rectangle (%d, %d, %d, %d) on canvas got a" | ||
316 | " rendering update.\n", rect->x, rect->y, | ||
317 | rect->w, | ||
318 | rect->h); | ||
319 | } | ||
320 | evas_render_updates_free(updates); | ||
321 | } | ||
322 | d.obscured = !d.obscured; | ||
323 | } /* end of obscured region command */ | ||
324 | } | ||
325 | |||
326 | int | ||
327 | main(void) | ||
328 | { | ||
329 | int err; | ||
330 | |||
331 | if (!ecore_evas_init()) | ||
332 | return EXIT_FAILURE; | ||
333 | |||
334 | /* this will give you a window with an Evas canvas under the first | ||
335 | * engine available */ | ||
336 | d.ee = ecore_evas_new(NULL, 10, 10, WIDTH, HEIGHT, NULL); | ||
337 | if (!d.ee) | ||
338 | goto error; | ||
339 | |||
340 | ecore_evas_callback_resize_set(d.ee, _canvas_resize_cb); | ||
341 | ecore_evas_show(d.ee); | ||
342 | |||
343 | /* the canvas pointer, de facto */ | ||
344 | d.canvas = ecore_evas_get(d.ee); | ||
345 | |||
346 | evas_event_callback_add(d.canvas, EVAS_CALLBACK_RENDER_FLUSH_PRE, | ||
347 | _render_flush_cb, NULL); | ||
348 | if (evas_alloc_error() != EVAS_ALLOC_ERROR_NONE) | ||
349 | { | ||
350 | fprintf(stderr, "ERROR: Callback registering failed! Aborting.\n"); | ||
351 | goto panic; | ||
352 | } | ||
353 | |||
354 | evas_event_callback_add(d.canvas, EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_IN, | ||
355 | _object_focus_in_cb, NULL); | ||
356 | if (evas_alloc_error() != EVAS_ALLOC_ERROR_NONE) | ||
357 | { | ||
358 | fprintf(stderr, "ERROR: Callback registering failed! Aborting.\n"); | ||
359 | goto panic; | ||
360 | } /* two canvas event callbacks */ | ||
361 | |||
362 | d.bg = evas_object_rectangle_add(d.canvas); | ||
363 | evas_object_name_set(d.bg, "our dear rectangle"); | ||
364 | evas_object_color_set(d.bg, 255, 255, 255, 255); /* white bg */ | ||
365 | evas_object_move(d.bg, 0, 0); /* at canvas' origin */ | ||
366 | evas_object_resize(d.bg, WIDTH, HEIGHT); /* covers full canvas */ | ||
367 | evas_object_show(d.bg); | ||
368 | |||
369 | evas_object_focus_set(d.bg, EINA_TRUE); /* so we get input events */ | ||
370 | d.focus = EINA_TRUE; | ||
371 | |||
372 | evas_object_event_callback_add( | ||
373 | d.bg, EVAS_CALLBACK_KEY_DOWN, _on_keydown, NULL); | ||
374 | if (evas_alloc_error() != EVAS_ALLOC_ERROR_NONE) | ||
375 | { | ||
376 | fprintf(stderr, "ERROR: Callback registering failed! Aborting.\n"); | ||
377 | goto panic; | ||
378 | } | ||
379 | |||
380 | d.img = evas_object_image_filled_add(d.canvas); | ||
381 | evas_object_image_file_set(d.img, img_path, NULL); | ||
382 | err = evas_object_image_load_error_get(d.img); | ||
383 | if (err != EVAS_LOAD_ERROR_NONE) | ||
384 | { | ||
385 | goto panic; | ||
386 | } | ||
387 | else | ||
388 | { | ||
389 | evas_object_move(d.img, 0, 0); | ||
390 | evas_object_resize(d.img, WIDTH, HEIGHT); | ||
391 | evas_object_show(d.img); | ||
392 | evas_object_event_callback_add( | ||
393 | d.img, EVAS_CALLBACK_MOUSE_IN, _on_mouse_in, NULL); | ||
394 | evas_object_event_callback_add( | ||
395 | d.img, EVAS_CALLBACK_MOUSE_OUT, _on_mouse_out, NULL); | ||
396 | } | ||
397 | |||
398 | d.resize_timer = ecore_timer_add(2, _resize_cb, NULL); | ||
399 | |||
400 | fprintf(stdout, commands); | ||
401 | ecore_main_loop_begin(); | ||
402 | |||
403 | ecore_evas_free(d.ee); | ||
404 | ecore_evas_shutdown(); | ||
405 | return 0; | ||
406 | |||
407 | error: | ||
408 | fprintf(stderr, "you got to have at least one evas engine built and linked" | ||
409 | " up to ecore-evas for this example to run properly.\n"); | ||
410 | panic: | ||
411 | ecore_evas_shutdown(); | ||
412 | return -1; | ||
413 | } | ||