Edje Signals example 2

In this example we will make use of signals to help to move an image away from the mouse pointer.

Signals are software interruption, this means that when it happens and if the program is sensitive to it the program will stop whatever it is doing and handle the signal.

In this example we are only sensitive to the "mouse,move" signal so we need to register a callback to it. To do this we will add a signal callback to our edje object that will detect "mouse,move" signal coming from the part "part_image" and when this happens we will call the function _on_mouse_over passing the evas pointer as a parameter. The evas pointer is passed as a parameter because we need to know where is the mouse pointer in the screen.

We can see bellow how we can listen to the signal:

edje_object_signal_callback_add(edje_obj, "mouse,move", "part_image",
_on_mouse_over, evas);
edje_object_signal_callback_add
void edje_object_signal_callback_add(Evas_Object *obj, const char *emission, const char *source, Edje_Signal_Cb func, void *data)
Adds a callback for an arriving Edje signal, emitted by a given Edje object.
Definition edje_legacy.c:85

Now, let's pass to the callback function. If we want to keep the ball away from the mouse pointer we need to now where is the ball and where is the mouse and we can easily discovery these things using this:

For the object position in the canvas:

evas_object_geometry_get(edje_obj, &x, &y, NULL, NULL);
evas_object_geometry_get
EVAS_API void evas_object_geometry_get(const Evas_Object *eo_obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
Retrieves the position and (rectangular) size of the given Evas object.
Definition evas_object_main.c:1335

For the mouse position relative to the screen:

evas_pointer_output_xy_get(evas, &mouseX, &mouseY);
evas_pointer_output_xy_get
EVAS_API void evas_pointer_output_xy_get(const Evas_Canvas *obj, int *x, int *y)
This function returns the current known default pointer coordinates.
Definition evas_canvas_eo.legacy.c:117

Now that we have the position of the mouse and the object we just need to set the new location and move the object. To set the new location we do this:

if ((rand() % 2) == 0)
x += ((mouseX - x) + (x / 4 + mouseY / 2));
else
x -= ((mouseX - x) + (x / 4 + mouseY / 2));
if ((rand() % 2) == 0)
y += ((mouseY - y) + (y / 4 + mouseX / 2));
else
y -= ((mouseY - y) + (y / 4 + mouseX / 2));

You can change the formula above if you like. Because we are changing the object's position we need to do something if the new position is beyond the canvas size. So here it is:

if (x > WIDTH)
x = WIDTH;
else if (x < 0) x = 0;
if (y > HEIGHT)
y = HEIGHT;
else if (y < 0) y = 0;

Then now what we need to do is move the object:

evas_object_move(edje_obj, x, y);
evas_object_move
EVAS_API void evas_object_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
Move the given Evas object to the given location inside its canvas' viewport.
Definition evas_object_main.c:1171

Here is the complete callback function:

_on_mouse_over(void *data, Evas_Object *edje_obj,
const char *emission EINA_UNUSED, const char *source EINA_UNUSED)
{
Evas *evas;
int x, y, mouseX, mouseY;
evas = (Evas *) data;
evas_object_geometry_get(edje_obj, &x, &y, NULL, NULL);
evas_pointer_output_xy_get(evas, &mouseX, &mouseY);
if ((rand() % 2) == 0)
x += ((mouseX - x) + (x / 4 + mouseY / 2));
else
x -= ((mouseX - x) + (x / 4 + mouseY / 2));
if ((rand() % 2) == 0)
y += ((mouseY - y) + (y / 4 + mouseX / 2));
else
y -= ((mouseY - y) + (y / 4 + mouseX / 2));
if (x > WIDTH)
x = WIDTH;
else if (x < 0) x = 0;
if (y > HEIGHT)
y = HEIGHT;
else if (y < 0) y = 0;
printf("Moving object to - (%d,%d)\n", x, y);
evas_object_move(edje_obj, x, y);
}
EINA_UNUSED
#define EINA_UNUSED
Used to indicate that a function parameter is purposely unused.
Definition eina_types.h:339
Evas
Eo Evas
An opaque handle to an Evas canvas.
Definition Evas_Common.h:163
Evas_Object
Efl_Canvas_Object Evas_Object
An Evas Object handle.
Definition Evas_Common.h:185

When you compile and run it you should see this:

The .edc file:

collections{
group{
name: "image_group";
max: 500 500;
min: 50 50;
images{
image: "bubble.png" COMP;
}
parts{
part{
name: "part_image";
type: IMAGE;
description{
min:63 63;
image{
normal: "bubble.png";
}
}
}
}
}
}

The source code:

//Compile with:
// edje_cc signalsBubble.edc && gcc -o signals2 signals2.c `pkg-config --libs --cflags ecore ecore-evas edje`
#ifdef HAVE_CONFIG_H
#include "config.h"
#else
#define PACKAGE_EXAMPLES_DIR "."
#define EINA_UNUSED
#endif
#ifndef PACKAGE_DATA_DIR
#define PACKAGE_DATA_DIR "."
#endif
#include <Ecore.h>
#include <Ecore_Evas.h>
#include <Edje.h>
#include <stdio.h>
#define WIDTH (700)
#define HEIGHT (700)
static void
_on_delete(Ecore_Evas *ee EINA_UNUSED)
{
ecore_main_loop_quit();
}
/* mouse over signals */
static void
_on_mouse_over(void *data, Evas_Object *edje_obj,
const char *emission EINA_UNUSED, const char *source EINA_UNUSED)
{
Evas *evas;
int x, y, mouseX, mouseY;
evas = (Evas *) data;
evas_object_geometry_get(edje_obj, &x, &y, NULL, NULL);
evas_pointer_output_xy_get(evas, &mouseX, &mouseY);
if ((rand() % 2) == 0)
x += ((mouseX - x) + (x / 4 + mouseY / 2));
else
x -= ((mouseX - x) + (x / 4 + mouseY / 2));
if ((rand() % 2) == 0)
y += ((mouseY - y) + (y / 4 + mouseX / 2));
else
y -= ((mouseY - y) + (y / 4 + mouseX / 2));
if (x > WIDTH)
x = WIDTH;
else if (x < 0) x = 0;
if (y > HEIGHT)
y = HEIGHT;
else if (y < 0) y = 0;
printf("Moving object to - (%d,%d)\n", x, y);
evas_object_move(edje_obj, x, y);
}
int
main(int argc EINA_UNUSED, char **argv EINA_UNUSED)
{
const char *edje_file = PACKAGE_DATA_DIR"/signalsBubble.edj";
Ecore_Evas *ee;
Evas *evas;
Evas_Object *bg;
Evas_Object *edje_obj;
if (!ecore_evas_init()) return EXIT_FAILURE;
if (!edje_init()) goto shutdown_ecore_evas;
ee = ecore_evas_new(NULL, 0, 0, WIDTH, HEIGHT, NULL);
if (!ee) goto shutdown_edje;
ecore_evas_callback_delete_request_set(ee, _on_delete);
ecore_evas_title_set(ee, "Edje animations and signals");
evas = ecore_evas_get(ee);
bg = evas_object_rectangle_add(evas);
evas_object_color_set(bg, 255, 255, 255, 255); //White
evas_object_move(bg, 0, 0); //orign
evas_object_resize(bg, WIDTH, HEIGHT); //cover the window
evas_object_show(bg);
ecore_evas_object_associate(ee, bg, ECORE_EVAS_OBJECT_ASSOCIATE_BASE);
evas_object_focus_set(bg, EINA_TRUE);
edje_obj = edje_object_add(evas);
if (!edje_object_file_set(edje_obj, edje_file, "image_group"))
{
int err = edje_object_load_error_get(edje_obj);
const char *errmsg = edje_load_error_str(err);
fprintf(stderr, "Could not load the edje file - reason:%s\n", errmsg);
goto shutdown_edje;
}
edje_object_signal_callback_add(edje_obj, "mouse,move", "part_image",
_on_mouse_over, evas);
evas_object_resize(edje_obj, 63, 63);
evas_object_move(edje_obj, 50, 50);
evas_object_show(edje_obj);
ecore_evas_show(ee);
ecore_main_loop_begin();
ecore_evas_free(ee);
edje_shutdown();
ecore_evas_shutdown();
return EXIT_SUCCESS;
shutdown_edje: edje_shutdown();
shutdown_ecore_evas: ecore_evas_shutdown();
return EXIT_FAILURE;
}
Ecore_Evas.h
Evas wrapper functions.
Edje.h
Edje Graphical Design Library.
ecore_evas_init
EAPI int ecore_evas_init(void)
Inits the Ecore_Evas system.
Definition ecore_evas.c:608
ecore_evas_title_set
EAPI void ecore_evas_title_set(Ecore_Evas *ee, const char *t)
Sets the title of an Ecore_Evas' window.
Definition ecore_evas.c:1541
ecore_evas_callback_delete_request_set
EAPI void ecore_evas_callback_delete_request_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func)
Sets a callback for Ecore_Evas delete request events.
Definition ecore_evas.c:1190
ecore_evas_show
EAPI void ecore_evas_show(Ecore_Evas *ee)
Shows an Ecore_Evas' window.
Definition ecore_evas.c:1494
ecore_evas_get
EAPI Evas * ecore_evas_get(const Ecore_Evas *ee)
Gets an Ecore_Evas's Evas.
Definition ecore_evas.c:1314
ecore_evas_new
EAPI Ecore_Evas * ecore_evas_new(const char *engine_name, int x, int y, int w, int h, const char *extra_options)
Creates a new Ecore_Evas based on engine name and common parameters.
Definition ecore_evas.c:1053
ecore_evas_shutdown
EAPI int ecore_evas_shutdown(void)
Shuts down the Ecore_Evas system.
Definition ecore_evas.c:672
ecore_evas_object_associate
EAPI Eina_Bool ecore_evas_object_associate(Ecore_Evas *ee, Evas_Object *obj, Ecore_Evas_Object_Associate_Flags flags)
Associates the given object to this ecore evas.
Definition ecore_evas_util.c:223
ecore_evas_free
EAPI void ecore_evas_free(Ecore_Evas *ee)
Frees an Ecore_Evas.
Definition ecore_evas.c:1097
ecore_main_loop_quit
void ecore_main_loop_quit(void)
Quits the main loop once all the events currently on the queue have been processed.
Definition ecore_main.c:1321
ecore_main_loop_begin
void ecore_main_loop_begin(void)
Runs the application main loop.
Definition ecore_main.c:1311
edje_shutdown
int edje_shutdown(void)
Shuts down the Edje library.
Definition edje_main.c:262
edje_init
int edje_init(void)
Initializes the Edje library.
Definition edje_main.c:35
edje_object_load_error_get
Edje_Load_Error edje_object_load_error_get(const Eo *obj)
Gets the (last) file loading error for a given Edje object.
Definition edje_legacy.c:15
edje_object_add
Evas_Object * edje_object_add(Evas *evas)
Instantiates a new Edje object.
Definition edje_smart.c:22
edje_load_error_str
const char * edje_load_error_str(Edje_Load_Error error)
Converts the given Edje file load error code into a string describing it in English.
Definition edje_load.c:108
edje_object_file_set
Eina_Bool edje_object_file_set(Evas_Object *obj, const char *file, const char *group)
Sets the EDJ file (and group within it) to load an Edje object's contents from.
Definition edje_smart.c:467
EINA_TRUE
#define EINA_TRUE
boolean value TRUE (numerical value 1)
Definition eina_types.h:539
evas_object_show
EVAS_API void evas_object_show(Evas_Object *eo_obj)
Makes the given Evas object visible.
Definition evas_object_main.c:1814
evas_object_color_set
EVAS_API void evas_object_color_set(Evas_Object *obj, int r, int g, int b, int a)
Sets the general/main color of the given Evas object to the given one.
Definition evas_object_main.c:2024
evas_object_focus_set
EVAS_API void evas_object_focus_set(Efl_Canvas_Object *obj, Eina_Bool focus)
Indicates that this object is the keyboard event receiver on its canvas.
Definition efl_canvas_object_eo.legacy.c:39
evas_object_resize
EVAS_API void evas_object_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
Changes the size of the given Evas object.
Definition evas_object_main.c:1236
evas_object_rectangle_add
EVAS_API Evas_Object * evas_object_rectangle_add(Evas *e)
Adds a rectangle to the given evas.
Definition evas_object_rectangle.c:78

To compile use this command:

    * gcc -o signals2 signals2.c -DPACKAGE_BIN_DIR=\"/Where/enlightenment/is/installed/bin\"
    * -DPACKAGE_LIB_DIR=\"/Where/enlightenment/is/installed/lib\"
    * -DPACKAGE_DATA_DIR=\"/Where/enlightenment/is/installed/share\"
    * `pkg-config --cflags --libs evas ecore ecore-evas edje`
    *
    * edje_cc -id /path/to/the/image signalsBubble.edc
    *