2 * Simple Evas example illustrating a custom Evas smart object
4 * You'll need at least one engine built for it (excluding the buffer
5 * one). See stdout/stderr for output.
8 * gcc -o evas-smart-object evas-smart-object.c `pkg-config --libs --cflags evas ecore ecore-evas`
17 #define PACKAGE_EXAMPLES_DIR "."
23 #include <Ecore_Evas.h>
30 static const char *commands = \
32 "\tl - insert child rectangle on the left\n"
33 "\tr - insert child rectangle on the right\n"
34 "\tright arrow - move smart object to the right\n"
35 "\tleft arrow - move smart object to the left\n"
36 "\tup arrow - move smart object up\n"
37 "\tdown arrow - move smart object down\n"
38 "\td - decrease smart object's size\n"
39 "\ti - increase smart object's size\n"
40 "\tc - change smart object's clipper color\n"
43 #define WHITE {255, 255, 255, 255}
44 #define RED {255, 0, 0, 255}
45 #define GREEN {0, 255, 0, 255}
46 #define BLUE {0, 0, 255, 255}
52 Evas_Object *smt, *bg, *clipper;
58 } clipper_colors[4] = {WHITE, RED, GREEN, BLUE};
62 _index_to_color(int i)
67 return "WHITE (default)";
83 static struct test_data d = {0};
84 static const char *border_img_path = PACKAGE_EXAMPLES_DIR "/red.png";
86 #define _evas_smart_example_type "Evas_Smart_Example"
87 #define SIG_CHILD_ADDED "child,added"
88 #define SIG_CHILD_REMOVED "child,removed"
90 static const Evas_Smart_Cb_Description _signals[] =
92 {SIG_CHILD_ADDED, ""},
93 {SIG_CHILD_REMOVED, ""},
97 typedef struct _Evas_Smart_Example_Data Evas_Smart_Example_Data;
99 * This structure augments clipped smart object's instance data,
100 * providing extra members required by our example smart object's
103 struct _Evas_Smart_Example_Data
105 Evas_Object_Smart_Clipped_Data base;
106 Evas_Object *children[2], *border;
109 #define EVAS_SMART_EXAMPLE_DATA_GET(o, ptr) \
110 Evas_Smart_Example_Data * ptr = evas_object_smart_data_get(o)
112 #define EVAS_SMART_EXAMPLE_DATA_GET_OR_RETURN(o, ptr) \
113 EVAS_SMART_EXAMPLE_DATA_GET(o, ptr); \
116 fprintf(stderr, "No widget data for object %p (%s)!", \
117 o, evas_object_type_get(o)); \
123 #define EVAS_SMART_EXAMPLE_DATA_GET_OR_RETURN_VAL(o, ptr, val) \
124 EVAS_SMART_EXAMPLE_DATA_GET(o, ptr); \
127 fprintf(stderr, "No widget data for object %p (%s)!", \
128 o, evas_object_type_get(o)); \
134 EVAS_SMART_SUBCLASS_NEW(_evas_smart_example_type, _evas_smart_example,
135 Evas_Smart_Class, Evas_Smart_Class,
136 evas_object_smart_clipped_class_get, _signals);
139 _on_destroy(Ecore_Evas *ee __UNUSED__)
141 ecore_main_loop_quit();
144 /* here just to keep our example's window size and background image's
145 * size in synchrony */
147 _canvas_resize_cb(Ecore_Evas *ee)
151 ecore_evas_geometry_get(ee, NULL, NULL, &w, &h);
152 evas_object_resize(d.bg, w, h);
156 _on_child_del(void *data,
157 Evas *evas __UNUSED__,
159 void *einfo __UNUSED__)
161 Evas_Object *example_smart = data;
164 EVAS_SMART_EXAMPLE_DATA_GET(example_smart, priv);
166 index = (int)evas_object_data_get(o, "index");
169 priv->children[index] = NULL;
171 evas_object_smart_member_del(o);
172 evas_object_smart_changed(example_smart);
176 _evas_smart_example_child_callbacks_unregister(Evas_Object *obj)
178 evas_object_data_set(obj, "index", NULL);
179 evas_object_event_callback_del(obj, EVAS_CALLBACK_FREE, _on_child_del);
183 _evas_smart_example_child_callbacks_register(Evas_Object *o,
187 evas_object_event_callback_add(child, EVAS_CALLBACK_FREE, _on_child_del, o);
188 evas_object_data_set(child, "index", (void *)(++index));
191 /* create and setup a new example smart object's internals */
193 _evas_smart_example_smart_add(Evas_Object *o)
195 EVAS_SMART_DATA_ALLOC(o, Evas_Smart_Example_Data);
197 /* this is a border around the smart object's area, delimiting it */
198 priv->border = evas_object_image_filled_add(evas_object_evas_get(o));
199 evas_object_image_file_set(priv->border, border_img_path, NULL);
200 evas_object_image_border_set(priv->border, 3, 3, 3, 3);
201 evas_object_image_border_center_fill_set(
202 priv->border, EVAS_BORDER_FILL_NONE);
203 evas_object_smart_member_add(priv->border, o);
205 _evas_smart_example_parent_sc->add(o);
209 _evas_smart_example_smart_del(Evas_Object *o)
211 EVAS_SMART_EXAMPLE_DATA_GET(o, priv);
213 if (priv->children[0])
215 _evas_smart_example_child_callbacks_unregister(priv->children[0]);
216 priv->children[0] = NULL;
219 if (priv->children[1])
221 _evas_smart_example_child_callbacks_unregister(priv->children[1]);
222 priv->children[1] = NULL;
225 _evas_smart_example_parent_sc->del(o);
229 _evas_smart_example_smart_show(Evas_Object *o)
231 EVAS_SMART_EXAMPLE_DATA_GET(o, priv);
233 if (priv->children[0]) evas_object_show(priv->children[0]);
234 if (priv->children[1]) evas_object_show(priv->children[1]);
235 evas_object_show(priv->border);
237 _evas_smart_example_parent_sc->show(o);
241 _evas_smart_example_smart_hide(Evas_Object *o)
243 EVAS_SMART_EXAMPLE_DATA_GET(o, priv);
245 if (priv->children[0]) evas_object_hide(priv->children[0]);
246 if (priv->children[1]) evas_object_hide(priv->children[1]);
247 evas_object_hide(priv->border);
249 _evas_smart_example_parent_sc->hide(o);
253 _evas_smart_example_smart_resize(Evas_Object *o,
258 evas_object_geometry_get(o, NULL, NULL, &ow, &oh);
259 if ((ow == w) && (oh == h)) return;
261 /* this will trigger recalculation */
262 evas_object_smart_changed(o);
265 /* act on child objects' properties, before rendering */
267 _evas_smart_example_smart_calculate(Evas_Object *o)
269 Evas_Coord x, y, w, h;
271 EVAS_SMART_EXAMPLE_DATA_GET_OR_RETURN(o, priv);
272 evas_object_geometry_get(o, &x, &y, &w, &h);
274 evas_object_resize(priv->border, w, h);
275 evas_object_move(priv->border, x, y);
277 if (priv->children[0])
279 evas_object_move(priv->children[0], x + 3, y + 3);
280 evas_object_resize(priv->children[0], (w / 2) - 3, (h / 2) - 3);
283 if (priv->children[1])
285 evas_object_move(priv->children[1], x + (w / 2), y + (h / 2));
286 evas_object_resize(priv->children[1], (w / 2) - 3, (h / 2) - 3);
290 /* setting our smart interface */
292 _evas_smart_example_smart_set_user(Evas_Smart_Class *sc)
294 /* specializing these two */
295 sc->add = _evas_smart_example_smart_add;
296 sc->del = _evas_smart_example_smart_del;
297 sc->show = _evas_smart_example_smart_show;
298 sc->hide = _evas_smart_example_smart_hide;
300 /* clipped smart object has no hook on resizes or calculations */
301 sc->resize = _evas_smart_example_smart_resize;
302 sc->calculate = _evas_smart_example_smart_calculate;
305 /* BEGINS example smart object's own interface */
307 /* add a new example smart object to a canvas */
309 evas_smart_example_add(Evas *evas)
311 return evas_object_smart_add(evas, _evas_smart_example_smart_class_new());
314 /* remove a child element, return its pointer (or NULL on errors) */
316 evas_smart_example_remove(Evas_Object *o,
321 EVAS_SMART_EXAMPLE_DATA_GET_OR_RETURN_VAL(o, priv, NULL);
323 if (priv->children[0] != child && priv->children[1] != child)
325 fprintf(stderr, "You are trying to remove something not belonging to"
326 " the example smart object!\n");
330 index = (int)evas_object_data_get(child, "index");
333 priv->children[index] = NULL;
335 evas_object_smart_callback_call(o, SIG_CHILD_REMOVED, child);
336 _evas_smart_example_child_callbacks_unregister(child);
337 evas_object_smart_member_del(child);
338 evas_object_smart_changed(o);
343 /* set to return any previous object set to the left position of the
344 * smart object or NULL, if any (or on errors) */
346 evas_smart_example_set_left(Evas_Object *o,
349 Evas_Object *ret = NULL;
351 EVAS_SMART_EXAMPLE_DATA_GET_OR_RETURN_VAL(o, priv, NULL);
355 if (priv->children[1] == child)
357 fprintf(stderr, "You mustn't place a child on both slots of"
358 " the example smart object!\n");
362 if (priv->children[0])
364 if (priv->children[0] != child)
365 ret = evas_smart_example_remove(o, priv->children[0]);
369 priv->children[0] = child;
370 evas_object_smart_callback_call(o, SIG_CHILD_ADDED, child);
372 _evas_smart_example_child_callbacks_register(o, child, 0);
373 evas_object_smart_member_add(child, o);
374 evas_object_smart_changed(o);
379 /* set to return any previous object set to the right position of the
380 * smart object or NULL, if any (or on errors) */
382 evas_smart_example_set_right(Evas_Object *o,
385 Evas_Object *ret = NULL;
387 EVAS_SMART_EXAMPLE_DATA_GET_OR_RETURN_VAL(o, priv, NULL);
391 if (priv->children[0] == child)
393 fprintf(stderr, "You mustn't place a child on both slots of"
394 " the example smart object!\n");
398 if (priv->children[1])
400 if (priv->children[1] != child)
401 ret = evas_smart_example_remove(o, priv->children[1]);
405 priv->children[1] = child;
406 evas_object_smart_callback_call(o, SIG_CHILD_ADDED, child);
408 _evas_smart_example_child_callbacks_register(o, child, 1);
409 evas_object_smart_member_add(child, o);
410 evas_object_smart_changed(o);
415 /* END OF example smart object's own interface */
418 _on_keydown(void *data __UNUSED__,
419 Evas *evas __UNUSED__,
420 Evas_Object *o __UNUSED__,
423 Evas_Event_Key_Down *ev = einfo;
425 if (strcmp(ev->keyname, "h") == 0) /* print help */
427 fprintf(stdout, commands);
431 if (strcmp(ev->keyname, "l") == 0) /* insert random colored
432 * rectangle on the left */
434 Evas_Object *rect = evas_object_rectangle_add(d.evas), *prev;
435 evas_object_color_set(
436 rect, rand() % 255, rand() % 255, rand() % 255, 255);
437 evas_object_show(rect);
439 prev = evas_smart_example_set_left(d.smt, rect);
440 fprintf(stdout, "Setting smart object's left spot with a new"
442 fprintf(stdout, "Checking its new smart object parent: %s\n",
443 evas_object_smart_parent_get(rect) == d.smt ? "OK!" :
449 evas_object_color_get(prev, &r, &g, &b, NULL);
450 fprintf(stdout, "Deleting previous left child,"
451 " which had colors (%d, %d, %d)\n", r, g, b);
452 evas_object_del(prev);
458 if (strcmp(ev->keyname, "r") == 0) /* insert random colored
459 * rectangle on the right */
461 Evas_Object *rect = evas_object_rectangle_add(d.evas), *prev;
462 evas_object_color_set(
463 rect, rand() % 255, rand() % 255, rand() % 255, 255);
464 evas_object_show(rect);
466 prev = evas_smart_example_set_right(d.smt, rect);
467 fprintf(stdout, "Setting smart object's right spot with a new"
469 fprintf(stdout, "Checking its new smart object parent: %s\n",
470 evas_object_smart_parent_get(rect) == d.smt ? "OK!" :
476 evas_object_color_get(prev, &r, &g, &b, NULL);
477 fprintf(stdout, "Deleting previous right child,"
478 " which had colors (%d, %d, %d)\n", r, g, b);
479 evas_object_del(prev);
485 /* move smart object along the canvas */
486 if (strcmp(ev->keyname, "Right") == 0 || strcmp(ev->keyname, "Left") == 0 ||
487 strcmp(ev->keyname, "Up") == 0 || strcmp(ev->keyname, "Down") == 0)
491 evas_object_geometry_get(d.smt, &x, &y, NULL, NULL);
493 switch (ev->keyname[0])
512 evas_object_move(d.smt, x, y);
517 /* increase smart object's size */
518 if (strcmp(ev->keyname, "i") == 0)
522 evas_object_geometry_get(d.smt, NULL, NULL, &w, &h);
527 evas_object_resize(d.smt, w, h);
532 /* decrease smart object's size */
533 if (strcmp(ev->keyname, "d") == 0)
537 evas_object_geometry_get(d.smt, NULL, NULL, &w, &h);
542 evas_object_resize(d.smt, w, h);
547 /* change smart object's clipper color */
548 if (strcmp(ev->keyname, "c") == 0)
550 cur_color = (cur_color + 1) % 4;
552 evas_object_color_set(
553 d.clipper, clipper_colors[cur_color].r, clipper_colors[cur_color].g,
554 clipper_colors[cur_color].b, clipper_colors[cur_color].a);
556 fprintf (stderr, "Changing clipper's color to %s\n",
557 _index_to_color(cur_color));
570 if (!ecore_evas_init())
573 /* this will give you a window with an Evas canvas under the first
574 * engine available */
575 d.ee = ecore_evas_new(NULL, 10, 10, WIDTH, HEIGHT, NULL);
579 ecore_evas_callback_destroy_set(d.ee, _on_destroy);
580 ecore_evas_callback_resize_set(d.ee, _canvas_resize_cb);
581 ecore_evas_show(d.ee);
583 /* the canvas pointer, de facto */
584 d.evas = ecore_evas_get(d.ee);
586 d.bg = evas_object_rectangle_add(d.evas);
587 evas_object_color_set(d.bg, 255, 255, 255, 255);
588 evas_object_move(d.bg, 0, 0);
589 evas_object_resize(d.bg, WIDTH, HEIGHT);
590 evas_object_show(d.bg);
592 d.smt = evas_smart_example_add(d.evas);
593 evas_object_move(d.smt, WIDTH / 4, HEIGHT / 4);
594 evas_object_resize(d.smt, WIDTH / 2, HEIGHT / 2);
595 evas_object_show(d.smt);
597 ret = evas_object_smart_type_check(d.smt, _evas_smart_example_type);
598 fprintf(stdout, "Adding smart object of type \"%s\" to the canvas: %s.\n",
599 _evas_smart_example_type, ret ? "success" : "failure");
601 d.clipper = evas_object_smart_clipped_clipper_get(d.smt);
602 fprintf(stdout, "Checking if clipped smart object's clipper is a "
603 "\"static\" one: %s\n", evas_object_static_clip_get(d.clipper) ?
606 evas_object_color_set(
607 d.clipper, clipper_colors[cur_color].r, clipper_colors[cur_color].g,
608 clipper_colors[cur_color].b, clipper_colors[cur_color].a);
610 evas_object_focus_set(d.bg, EINA_TRUE);
611 evas_object_event_callback_add(
612 d.bg, EVAS_CALLBACK_KEY_DOWN, _on_keydown, NULL);
614 fprintf(stdout, commands);
615 ecore_main_loop_begin();
617 ecore_evas_free(d.ee);
618 ecore_evas_shutdown();
622 fprintf(stderr, "you got to have at least one evas engine built and linked"
623 " up to ecore-evas for this example to run properly.\n");
624 ecore_evas_shutdown();