Box example - basic usage

This example shows how to append, insert and remove elements from an Edje box part.

It will make use of the edje_object_part_box functions.

To play with this example, use mouse left click to delete an existing rectangle from the box and right mouse click to add a new rectangle just before the clicked one. Use the keyboard keys "a" to append a rectangle, "i" to prepend, and "c" to remove all rectangles from the box.

We will store our example global information in the data structure defined below, and also set some callbacks for resizing the canvas and exiting the window:

static const char commands[] = \
"commands are:\n"
"\ti - prepend rectangle\n"
"\ta - append rectangle\n"
"\tc - remove\n"
"\tEsc - exit\n"
"\th - print help\n";
static void
_on_destroy(Ecore_Evas *ee EINA_UNUSED)
{
ecore_main_loop_quit();
}
/* here just to keep our example's window size and background image's
* size in synchrony */
static void
_on_canvas_resize(Ecore_Evas *ee)
{
Evas_Object *bg;
Evas_Object *edje_obj;
int w;
int h;
bg = ecore_evas_data_get(ee, "background");
edje_obj = ecore_evas_data_get(ee, "edje_obj");
ecore_evas_geometry_get(ee, NULL, NULL, &w, &h);
ecore_evas_geometry_get
EAPI void ecore_evas_geometry_get(const Ecore_Evas *ee, int *x, int *y, int *w, int *h)
Gets the geometry of an Ecore_Evas.
Definition: ecore_evas.c:1362
ecore_evas_data_get
EAPI void * ecore_evas_data_get(const Ecore_Evas *ee, const char *key)
Retrieves user data associated with an Ecore_Evas.
Definition: ecore_evas.c:1092
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
EINA_UNUSED
#define EINA_UNUSED
Used to indicate that a function parameter is purposely unused.
Definition: eina_types.h:339
Evas_Object
Efl_Canvas_Object Evas_Object
An Evas Object handle.
Definition: Evas_Common.h:185
evas_object_resize(bg, w, h);
evas_object_resize(edje_obj, w, h);
}
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

In the `main` function, we create our `Ecore_Evas`, add a background to it, and finally load our `Edje` file that contains a `Box` part. This part is named `"example/box"` in this case, and we use this name to append elements to it.

The code until now is the one that follows:

Also notice that we set the callback `_bg_key_down` for `"key down"` events on the background object, and that object is the one with focus.

Now we add some small rectangles to the box part, using the edje_object_part_box_append() API, and set some callbacks for `"mouse down"` events on every object. These callbacks will be used to add or delete objects from the box part.

bg = evas_object_rectangle_add(evas);
evas_object_color_set(bg, 255, 255, 255, 255);
evas_object_resize(bg, WIDTH, HEIGHT);
evas_object_focus_set(bg, EINA_TRUE);
evas_object_show(bg);
ecore_evas_data_set(ee, "background", bg);
evas_object_event_callback_add(bg, EVAS_CALLBACK_KEY_DOWN, _on_bg_key_down, ee);
EVAS_CALLBACK_KEY_DOWN
@ EVAS_CALLBACK_KEY_DOWN
Key Press Event.
Definition: Evas_Common.h:430
ecore_evas_data_set
EAPI void ecore_evas_data_set(Ecore_Evas *ee, const char *key, const void *data)
Stores user data in an Ecore_Evas structure.
Definition: ecore_evas.c:1103
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_event_callback_add
EVAS_API void evas_object_event_callback_add(Evas_Object *eo_obj, Evas_Callback_Type type, Evas_Object_Event_Cb func, const void *data)
Add (register) a callback function to a given Evas object event.
Definition: evas_callbacks.c:478
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_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
edje_obj = edje_object_add(evas);
edje_object_file_set(edje_obj, edje_file, "example/group");
evas_object_move(edje_obj, 0, 0);
evas_object_resize(edje_obj, WIDTH, HEIGHT);
evas_object_show(edje_obj);
ecore_evas_data_set(ee, "edje_obj", edje_obj);
for (i = 0; i < NRECTS; i++)
{
Evas_Object *rect;
Eina_Bool r = EINA_FALSE;
int red = (i * 10) % 256;
rect = evas_object_rectangle_add(evas);
evas_object_color_set(rect, red, 0, 0, 255);
evas_object_resize(rect, RECTW, RECTH);
r = edje_object_part_box_append(edje_obj, "example/box", rect);
if (!r)
printf("An error occurred when appending rect #%d to the box.\n", i);
evas_object_show(rect);
evas_object_event_callback_add(
rect, EVAS_CALLBACK_MOUSE_DOWN, _on_rect_mouse_down, ee);
}
EVAS_CALLBACK_MOUSE_DOWN
@ EVAS_CALLBACK_MOUSE_DOWN
Mouse Button Down Event.
Definition: Evas_Common.h:422
edje_object_add
Evas_Object * edje_object_add(Evas *evas)
Instantiates a new Edje object.
Definition: edje_smart.c:22
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
edje_object_part_box_append
Eina_Bool edje_object_part_box_append(Evas_Object *obj, const char *part, Evas_Object *child)
Appends an object to the box.
Definition: edje_part_table.c:232
EINA_FALSE
#define EINA_FALSE
boolean value FALSE (numerical value 0)
Definition: eina_types.h:533
Eina_Bool
unsigned char Eina_Bool
Type to mimic a boolean.
Definition: eina_types.h:527
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

Now let's take a look at the callbacks for key down and mouse down events:

static void
_on_rect_mouse_down(void *data, Evas *e, Evas_Object *o, void *event_info)
{
Ecore_Evas *ee;
Evas_Event_Mouse_Down *ev;
Evas_Object *edje_obj;
ee = (Ecore_Evas *)data;
ev = (Evas_Event_Mouse_Down *)event_info;
edje_obj = ecore_evas_data_get(ee, "edje_obj");
if (ev->button == 1)
{
printf("Removing rect %p under the mouse pointer.\n", o);
edje_object_part_box_remove(edje_obj, "example/box", o);
evas_object_del(o);
}
else if (ev->button == 3)
{
Evas_Object *rect;
Eina_Bool r;
rect = evas_object_rectangle_add(e);
evas_object_color_set(rect, 0, 0, 255, 255);
evas_object_resize(rect, RECTW + 10, RECTH);
evas_object_show(rect);
printf("Inserting rect %p before the rectangle under the mouse pointer.\n", rect);
r = edje_object_part_box_insert_before(edje_obj, "example/box", rect, o);
if (!r)
printf("An error occurred when appending rect %p to the box.\n", rect);
evas_object_event_callback_add(rect, EVAS_CALLBACK_MOUSE_DOWN, _on_rect_mouse_down, NULL);
edje_object_part_box_remove
Evas_Object * edje_object_part_box_remove(Evas_Object *obj, const char *part, Evas_Object *child)
Removes an object from the box.
Definition: edje_part_table.c:274
edje_object_part_box_insert_before
Eina_Bool edje_object_part_box_insert_before(Evas_Object *obj, const char *part, Evas_Object *child, const Evas_Object *reference)
Adds an object to the box.
Definition: edje_part_table.c:246
Evas
Eo Evas
An opaque handle to an Evas canvas.
Definition: Evas_Common.h:163
evas_object_del
EVAS_API void evas_object_del(Evas_Object *obj)
Marks the given Evas object for deletion (when Evas will free its memory).
Definition: evas_object_main.c:928
_Evas_Event_Mouse_Down
Mouse button press event.
Definition: Evas_Legacy.h:160
_Evas_Event_Mouse_Down::button
int button
Mouse button number that went down (1 - 32)
Definition: Evas_Legacy.h:161
}
}

This callback for mouse down events will get left clicks and remove the object that received that left click from the box part, and then delete it. This is done with the edje_object_part_box_remove() function.

However, on right clicks it will create a new rectangle object, and add it just before the right clicked object, using edje_object_part_box_insert_before().

And this is the key down callback:

static void
_on_bg_key_down(void *data, Evas *e, Evas_Object *o EINA_UNUSED, void *event_info)
{
Ecore_Evas *ee;
Evas_Event_Key_Down *ev;
Evas_Object *edje_obj;
Evas_Object *rect;
Eina_Bool r;
ee = (Ecore_Evas *)data;
ev = (Evas_Event_Key_Down *)event_info;
edje_obj = ecore_evas_data_get(ee, "edje_obj");
if (!strcmp(ev->key, "h"))
{
printf(commands);
return;
}
if (!strcmp(ev->key, "i"))
{
rect = evas_object_rectangle_add(e);
evas_object_color_set(rect, 0, 0, 128, 255);
evas_object_resize(rect, RECTW + 30, RECTH);
evas_object_show(rect);
printf("Inserting rect %p before the rectangle under the mouse pointer.\n", rect);
r = edje_object_part_box_insert_at(edje_obj, "example/box", rect, 0);
if (!r)
printf("An error occurred when appending rect %p to the box.\n", rect);
evas_object_event_callback_add(rect, EVAS_CALLBACK_MOUSE_DOWN, _on_rect_mouse_down, NULL);
}
else if (!strcmp(ev->key, "a"))
{
rect = evas_object_rectangle_add(e);
evas_object_color_set(rect, 0, 128, 0, 255);
evas_object_resize(rect, RECTW, RECTH);
evas_object_show(rect);
printf("Inserting rect %p before the rectangle under the mouse pointer.\n", rect);
r = edje_object_part_box_append(edje_obj, "example/box", rect);
if (!r)
printf("An error occurred when appending rect %p to the box.\n", rect);
evas_object_event_callback_add(rect, EVAS_CALLBACK_MOUSE_DOWN, _on_rect_mouse_down, NULL);
}
else if (!strcmp(ev->key, "c"))
edje_object_part_box_remove_all(edje_obj, "example/box", EINA_TRUE);
edje_object_part_box_insert_at
Eina_Bool edje_object_part_box_insert_at(Evas_Object *obj, const char *part, Evas_Object *child, unsigned int pos)
Inserts an object to the box.
Definition: edje_part_table.c:260
edje_object_part_box_remove_all
Eina_Bool edje_object_part_box_remove_all(Evas_Object *obj, const char *part, Eina_Bool clear)
Removes all elements from the box.
Definition: edje_part_table.c:283
_Evas_Event_Key_Down
Key press event.
Definition: Evas_Legacy.h:314
_Evas_Event_Key_Down::key
const char * key
The logical key : (eg shift+1 == exclamation)
Definition: Evas_Legacy.h:320
else if (!strcmp(ev->key, "Escape"))
ecore_main_loop_quit();
else
{
printf("unhandled key: %s\n", ev->key);
printf(commands);
}

It will insert elements at the beginning of the box if "i" was pressed, using edje_object_part_box_insert_at(). It will also append objects to the box if "a" was pressed, just exactly like we did in the `main` function. And will remove all objects (deleting them) if "c" was pressed.

As you can see, this example uses the `"horizontal_flow"` layout for the box, where each item is put linearly in rows, in as many rows as necessary to store all of them.

The example's window should look like this picture:

The full source code follows:

#ifdef HAVE_CONFIG_H
# include "config.h"
#else
# define EINA_UNUSED
#endif
#ifndef PACKAGE_DATA_DIR
#define PACKAGE_DATA_DIR "."
#endif
#include <Ecore.h>
#include <Ecore_Evas.h>
#include <Edje.h>
#define WIDTH 300
#define HEIGHT 300
#define RECTW 30
#define RECTH 30
#define NRECTS 20
static const char commands[] = \
"commands are:\n"
"\ti - prepend rectangle\n"
"\ta - append rectangle\n"
"\tc - remove\n"
"\tEsc - exit\n"
"\th - print help\n";
static void
_on_destroy(Ecore_Evas *ee EINA_UNUSED)
{
ecore_main_loop_quit();
}
/* here just to keep our example's window size and background image's
* size in synchrony */
static void
_on_canvas_resize(Ecore_Evas *ee)
{
Evas_Object *bg;
Evas_Object *edje_obj;
int w;
int h;
bg = ecore_evas_data_get(ee, "background");
edje_obj = ecore_evas_data_get(ee, "edje_obj");
ecore_evas_geometry_get(ee, NULL, NULL, &w, &h);
evas_object_resize(bg, w, h);
evas_object_resize(edje_obj, w, h);
}
static void
_on_rect_mouse_down(void *data, Evas *e, Evas_Object *o, void *event_info)
{
Ecore_Evas *ee;
Evas_Event_Mouse_Down *ev;
Evas_Object *edje_obj;
ee = (Ecore_Evas *)data;
ev = (Evas_Event_Mouse_Down *)event_info;
edje_obj = ecore_evas_data_get(ee, "edje_obj");
if (ev->button == 1)
{
printf("Removing rect %p under the mouse pointer.\n", o);
edje_object_part_box_remove(edje_obj, "example/box", o);
evas_object_del(o);
}
else if (ev->button == 3)
{
Evas_Object *rect;
Eina_Bool r;
rect = evas_object_rectangle_add(e);
evas_object_color_set(rect, 0, 0, 255, 255);
evas_object_resize(rect, RECTW + 10, RECTH);
evas_object_show(rect);
printf("Inserting rect %p before the rectangle under the mouse pointer.\n", rect);
r = edje_object_part_box_insert_before(edje_obj, "example/box", rect, o);
if (!r)
printf("An error occurred when appending rect %p to the box.\n", rect);
evas_object_event_callback_add(rect, EVAS_CALLBACK_MOUSE_DOWN, _on_rect_mouse_down, NULL);
}
}
static void
_on_bg_key_down(void *data, Evas *e, Evas_Object *o EINA_UNUSED, void *event_info)
{
Ecore_Evas *ee;
Evas_Event_Key_Down *ev;
Evas_Object *edje_obj;
Evas_Object *rect;
Eina_Bool r;
ee = (Ecore_Evas *)data;
ev = (Evas_Event_Key_Down *)event_info;
edje_obj = ecore_evas_data_get(ee, "edje_obj");
if (!strcmp(ev->key, "h"))
{
printf(commands);
return;
}
if (!strcmp(ev->key, "i"))
{
rect = evas_object_rectangle_add(e);
evas_object_color_set(rect, 0, 0, 128, 255);
evas_object_resize(rect, RECTW + 30, RECTH);
evas_object_show(rect);
printf("Inserting rect %p before the rectangle under the mouse pointer.\n", rect);
r = edje_object_part_box_insert_at(edje_obj, "example/box", rect, 0);
if (!r)
printf("An error occurred when appending rect %p to the box.\n", rect);
evas_object_event_callback_add(rect, EVAS_CALLBACK_MOUSE_DOWN, _on_rect_mouse_down, NULL);
}
else if (!strcmp(ev->key, "a"))
{
rect = evas_object_rectangle_add(e);
evas_object_color_set(rect, 0, 128, 0, 255);
evas_object_resize(rect, RECTW, RECTH);
evas_object_show(rect);
printf("Inserting rect %p before the rectangle under the mouse pointer.\n", rect);
r = edje_object_part_box_append(edje_obj, "example/box", rect);
if (!r)
printf("An error occurred when appending rect %p to the box.\n", rect);
evas_object_event_callback_add(rect, EVAS_CALLBACK_MOUSE_DOWN, _on_rect_mouse_down, NULL);
}
else if (!strcmp(ev->key, "c"))
edje_object_part_box_remove_all(edje_obj, "example/box", EINA_TRUE);
else if (!strcmp(ev->key, "Escape"))
ecore_main_loop_quit();
else
{
printf("unhandled key: %s\n", ev->key);
printf(commands);
}
}
int
main(int argc EINA_UNUSED, char *argv[] EINA_UNUSED)
{
const char *edje_file = PACKAGE_DATA_DIR"/box.edj";
Ecore_Evas *ee;
Evas *evas;
Evas_Object *bg;
Evas_Object *edje_obj;
int i;
if (!ecore_evas_init())
return EXIT_FAILURE;
if (!edje_init())
goto shutdown_ecore_evas;
/* this will give you a window with an Evas canvas under the first
* engine available */
ee = ecore_evas_new(NULL, 0, 0, WIDTH, HEIGHT, NULL);
if (!ee) goto shutdown_edje;
ecore_evas_callback_destroy_set(ee, _on_destroy);
ecore_evas_callback_resize_set(ee, _on_canvas_resize);
ecore_evas_title_set(ee, "Edje Box Example");
evas = ecore_evas_get(ee);
bg = evas_object_rectangle_add(evas);
evas_object_color_set(bg, 255, 255, 255, 255);
evas_object_resize(bg, WIDTH, HEIGHT);
evas_object_focus_set(bg, EINA_TRUE);
evas_object_show(bg);
ecore_evas_data_set(ee, "background", bg);
evas_object_event_callback_add(bg, EVAS_CALLBACK_KEY_DOWN, _on_bg_key_down, ee);
edje_obj = edje_object_add(evas);
edje_object_file_set(edje_obj, edje_file, "example/group");
evas_object_move(edje_obj, 0, 0);
evas_object_resize(edje_obj, WIDTH, HEIGHT);
evas_object_show(edje_obj);
ecore_evas_data_set(ee, "edje_obj", edje_obj);
for (i = 0; i < NRECTS; i++)
{
Evas_Object *rect;
Eina_Bool r = EINA_FALSE;
int red = (i * 10) % 256;
rect = evas_object_rectangle_add(evas);
evas_object_color_set(rect, red, 0, 0, 255);
evas_object_resize(rect, RECTW, RECTH);
r = edje_object_part_box_append(edje_obj, "example/box", rect);
if (!r)
printf("An error occurred when appending rect #%d to the box.\n", i);
evas_object_show(rect);
evas_object_event_callback_add(
rect, EVAS_CALLBACK_MOUSE_DOWN, _on_rect_mouse_down, ee);
}
printf(commands);
ecore_evas_show(ee);
ecore_main_loop_begin();
ecore_evas_free(ee);
ecore_evas_shutdown();
edje_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:602
ecore_evas_callback_destroy_set
EAPI void ecore_evas_callback_destroy_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func)
Sets a callback for Ecore_Evas destroy events.
Definition: ecore_evas.c:1185
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:1527
ecore_evas_show
EAPI void ecore_evas_show(Ecore_Evas *ee)
Shows an Ecore_Evas' window.
Definition: ecore_evas.c:1480
ecore_evas_get
EAPI Evas * ecore_evas_get(const Ecore_Evas *ee)
Gets an Ecore_Evas's Evas.
Definition: ecore_evas.c:1300
ecore_evas_callback_resize_set
EAPI void ecore_evas_callback_resize_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func)
Sets a callback for Ecore_Evas resize events.
Definition: ecore_evas.c:1140
ecore_evas_shutdown
EAPI int ecore_evas_shutdown(void)
Shuts down the Ecore_Evas system.
Definition: ecore_evas.c:666
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:1039
ecore_evas_free
EAPI void ecore_evas_free(Ecore_Evas *ee)
Frees an Ecore_Evas.
Definition: ecore_evas.c:1083
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

To compile use this command:

    * gcc -o edje-box edje-box.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 box.edc
    *