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);

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);

For the mouse position relative to the screen:

evas_pointer_output_xy_get(evas, &mouseX, &mouseY);

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);

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);
}

When you compile and run it you should see this:

signal2final.png

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)
{
}
/* 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 *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_title_set(ee, "Edje animations and signals");
evas = ecore_evas_get(ee);
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
ecore_evas_object_associate(ee, bg, ECORE_EVAS_OBJECT_ASSOCIATE_BASE);
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);
return EXIT_SUCCESS;
shutdown_edje: edje_shutdown();
shutdown_ecore_evas: ecore_evas_shutdown();
return EXIT_FAILURE;
}

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
*