Edje Color Class example

This example shows how to manipulate and change Color classes. In this example we will create two surfaces to show what happens when you change the color class at the process and object level.

It's a very simple example, there are two surfaces created from the same EDC, but just in one of them we will set a specific color class, although both will be affected by color class set at the process level as you will see.

It's important you know that all colors has the format R G B A. Just to be easier to understand this example, we will create a small set of colors that will be used along of the example. This piece of code is shown below:

static color colors_init_data[] =
{{255, 0, 0, 255}, /* red */
{0, 255, 0, 255}, /* green */
{0, 0, 255, 255}, /* blue */
{0, 0, 0, 255}, /* black */
{255, 255, 255, 255}, /* white */
{128, 128, 128, 255}, /* gray */
{255, 255, 0, 255}, /* yellow */
{255, 0, 255, 255} /* pink */
};
static char *color_names[] =
{"red", "green", "blue", "black", "white",
"gray", "yellow", "pink"};
static Eina_Bool
_get_color_from_name(const char *n, color *c)
{
int i;
for (i = 0; i < 8; i++)
if (!strcmp(n, color_names[i]))
{
(*c)[0] = (colors_init_data[i])[0];
(*c)[1] = (colors_init_data[i])[1];
(*c)[2] = (colors_init_data[i])[2];
(*c)[3] = (colors_init_data[i])[3];
return EINA_TRUE;
}
return EINA_FALSE;
}

Focusing on the relevant parts of the code we go right to the part where we set the new color class. For that we will use the functions edje_color_class_set ( which will affect all edjes) and edje_object_color_class_set (which affects just the specific object).

edje_color_class_set(argv[1], /* class name */
c1[0], c1[1], c1[2], c1[3], /* Object color */
c2[0], c2[1], c2[2], c2[3], /* Text outline */
c3[0], c3[1], c3[2], c3[3]); /* Text shadow */
/* Setting an arbitrary value just to see the difference between */
/* process level and object level */
edje_object_color_class_set(edje_obj2, argv[1], /* class name */
128, 180, 77, 255, /* Object color */
200, 22, 86, 255, /* Text outline */
39, 90, 187, 255); /* Text shadow */
Note
  • argv[1] is the name of a color class used in the EDC.
  • The second and third colors only apply to text part.
  • The color class set for the object overrides the color previously set.

After we have set the color class we will check the color classes, for that we created a function which prints all color classes and tries to get theirs values and print too.

_color_classes_print(void)
{
Eina_List *classes;
char *class_name;
printf("Getting the color classes\n\n");
classes = edje_color_class_list();
EINA_LIST_FREE(classes, class_name)
{
int r1, r2, r3, g1, g2, g3, b1, b2, b3,
a1, a2, a3;
printf("\ncolor class: %s\n", class_name);
if (!edje_color_class_get(class_name, &r1, &g1, &b1, &a1,
&r2, &g2, &b2, &a2, &r3, &g3, &b3, &a3))
fprintf(stderr, "Cannot get the color class\n");
else
{
printf("Object color r: %d g: %d b: %d a: %d\n",
r1, g1, b1, a1);
printf("Text outline color r: %d g: %d b: %d a: %d\n",
r2, g2, b2, a2);
printf("Text shadow color r: %d g: %d b: %d a: %d\n",
r3, g3, b3, a3);
}
free(class_name);
}
}

There are two other things that are worth mentioning, we added two callbacks for the objects, one for mouse down (that we use to delete the color class) and another for the signal emitted when a color class is deleted.

_on_mouse_down, NULL);
edje_object_signal_callback_add(edje_obj1, "color_class,del", "*",
(Edje_Signal_Cb) _color_class_callback_delete,
"process");

And then we delete the color class:

_on_mouse_down(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info)
{
Evas_Event_Mouse_Down *ev = event_info;
if (ev->button == 1)
{
if (obj == edje_obj1)
edje_color_class_del(selected_class);
else
edje_object_color_class_del(edje_obj2, selected_class);
}

Our example will look like this, if you run with the parameters "green_class gray pink yellow":


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 (400)
#define HEIGHT (400)
typedef int color[4]; /* rgba */
static Ecore_Evas *ee1, *ee2;
static Evas *evas1, *evas2;
static Evas_Object *bg1, *edje_obj1, *bg2, *edje_obj2;
static const char *selected_class;
static color colors_init_data[] =
{{255, 0, 0, 255}, /* red */
{0, 255, 0, 255}, /* green */
{0, 0, 255, 255}, /* blue */
{0, 0, 0, 255}, /* black */
{255, 255, 255, 255}, /* white */
{128, 128, 128, 255}, /* gray */
{255, 255, 0, 255}, /* yellow */
{255, 0, 255, 255} /* pink */
};
static char *color_names[] =
{"red", "green", "blue", "black", "white",
"gray", "yellow", "pink"};
static Eina_Bool
_get_color_from_name(const char *n, color *c)
{
int i;
for (i = 0; i < 8; i++)
if (!strcmp(n, color_names[i]))
{
(*c)[0] = (colors_init_data[i])[0];
(*c)[1] = (colors_init_data[i])[1];
(*c)[2] = (colors_init_data[i])[2];
(*c)[3] = (colors_init_data[i])[3];
return EINA_TRUE;
}
return EINA_FALSE;
}
static void
_color_classes_print(void)
{
Eina_List *classes;
char *class_name;
printf("Getting the color classes\n\n");
classes = edje_color_class_list();
EINA_LIST_FREE(classes, class_name)
{
int r1, r2, r3, g1, g2, g3, b1, b2, b3,
a1, a2, a3;
printf("\ncolor class: %s\n", class_name);
if (!edje_color_class_get(class_name, &r1, &g1, &b1, &a1,
&r2, &g2, &b2, &a2, &r3, &g3, &b3, &a3))
fprintf(stderr, "Cannot get the color class\n");
else
{
printf("Object color r: %d g: %d b: %d a: %d\n",
r1, g1, b1, a1);
printf("Text outline color r: %d g: %d b: %d a: %d\n",
r2, g2, b2, a2);
printf("Text shadow color r: %d g: %d b: %d a: %d\n",
r3, g3, b3, a3);
}
free(class_name);
}
}
static void
_on_destroy(Ecore_Evas *ee EINA_UNUSED)
{
}
static void
_on_mouse_down(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info)
{
Evas_Event_Mouse_Down *ev = event_info;
if (ev->button == 1)
{
if (obj == edje_obj1)
edje_color_class_del(selected_class);
else
edje_object_color_class_del(edje_obj2, selected_class);
}
}
/* here just to keep our example's window size
* in synchrony. */
static void
_canvas_resize_cb(Ecore_Evas *_ee)
{
int w, h;
ecore_evas_geometry_get(_ee, NULL, NULL, &w, &h);
if (_ee == ee1)
{
evas_object_resize(bg1, w, h);
evas_object_resize(edje_obj1, w, h);
}
else
{
evas_object_resize(bg2, w, h);
evas_object_resize(edje_obj2, w, h);
}
}
static void
_color_class_callback_delete(void *data, Evas_Object *obj EINA_UNUSED,
const char *emission, void *source EINA_UNUSED)
{
if (!strcmp(data, "process"))
printf("Color class: %s deleted on process level\n", emission);
else
printf("Color class: %s deleted on object level\n", emission);
}
static int
_create_windows(const char *edje_file_path)
{
/* this will give you a window with an Evas canvas under the first
* engine available */
ee1 = ecore_evas_new(NULL, 0, 0, WIDTH, HEIGHT, NULL);
if (!ee1)
return 0;
ee2 = ecore_evas_new(NULL, 0, 0, WIDTH, HEIGHT, NULL);
if (!ee2)
return 0;
ecore_evas_callback_resize_set(ee1, _canvas_resize_cb);
ecore_evas_title_set(ee1, "Edje Color Class Example");
ecore_evas_callback_resize_set(ee2, _canvas_resize_cb);
ecore_evas_title_set(ee2, "Edje Object Color Class Example");
evas1 = ecore_evas_get(ee1);
evas2 = ecore_evas_get(ee2);
evas_object_color_set(bg1, 255, 255, 255, 255); /* white bg */
evas_object_move(bg1, 0, 0); /* at canvas' origin */
evas_object_resize(bg1, WIDTH, HEIGHT); /* covers full canvas */
evas_object_color_set(bg2, 255, 255, 255, 255); /* white bg */
evas_object_move(bg2, 0, 0); /* at canvas' origin */
evas_object_resize(bg2, WIDTH, HEIGHT); /* covers full canvas */
edje_obj1 = edje_object_add(evas1);
_on_mouse_down, NULL);
edje_object_file_set(edje_obj1, edje_file_path, "example_color_class");
evas_object_move(edje_obj1, 0, 0); /* at canvas' origin */
evas_object_resize(edje_obj1, WIDTH, HEIGHT);
edje_object_part_text_set(edje_obj1, "part_four", "EDJE EXAMPLE");
edje_object_signal_callback_add(edje_obj1, "color_class,del", "*",
(Edje_Signal_Cb) _color_class_callback_delete,
"process");
evas_object_show(edje_obj1);
edje_obj2 = edje_object_add(evas2);
_on_mouse_down, NULL);
edje_object_file_set(edje_obj2, edje_file_path, "example_color_class");
evas_object_move(edje_obj2, 0, 0); /* at canvas' origin */
evas_object_resize(edje_obj2, WIDTH, HEIGHT);
edje_object_part_text_set(edje_obj2, "part_four", "EDJE OBJECT EXAMPLE");
edje_object_signal_callback_add(edje_obj2, "color_class,del", "*",
(Edje_Signal_Cb) _color_class_callback_delete,
"object");
evas_object_show(edje_obj2);
return 1;
}
int
main(int argc, char *argv[])
{
const char *edje_file = PACKAGE_DATA_DIR"/color-class.edj";
color c1, c2, c3;
int i;
if (argc != 5)
{
fprintf(stderr, "You have to use: %s color_class_name color1, color2," \
"color3\n", argv[0]);
fprintf(stderr, "Available colors:\n");
for (i = 0; i < 8; i++)
fprintf(stderr, "%s\n", color_names[i]);
return EXIT_FAILURE;
}
selected_class = argv[1];
if (!(_get_color_from_name(argv[2], &c1) &&
_get_color_from_name(argv[3], &c2) &&
_get_color_from_name(argv[4], &c3)))
{
fprintf(stderr, "Color not available!\n");
return EXIT_FAILURE;
}
return EXIT_FAILURE;
if (!edje_init())
goto shutdown_ecore_evas;
if (!_create_windows(edje_file)) goto shutdown_edje;
edje_color_class_set(argv[1], /* class name */
c1[0], c1[1], c1[2], c1[3], /* Object color */
c2[0], c2[1], c2[2], c2[3], /* Text outline */
c3[0], c3[1], c3[2], c3[3]); /* Text shadow */
/* Setting an arbitrary value just to see the difference between */
/* process level and object level */
edje_object_color_class_set(edje_obj2, argv[1], /* class name */
128, 180, 77, 255, /* Object color */
200, 22, 86, 255, /* Text outline */
39, 90, 187, 255); /* Text shadow */
_color_classes_print();
return EXIT_SUCCESS;
shutdown_edje:
shutdown_ecore_evas:
return EXIT_FAILURE;
}

The theme used in this example is:

color_classes {
color_class {
name: "red_class";
color: 255 0 0 255; /* red */
color2: 255 0 0 255; /* red */
color3: 255 0 0 255; /* red */
}
color_class {
name: "green_class";
color: 0 255 0 255; /* green */
color2: 0 255 0 255; /* green */
color3: 0 255 0 255; /* green */
}
color_class {
name: "blue_class";
color: 0 0 255 255; /* blue */
color2: 0 0 255 255; /* blue */
color3: 0 0 255 255; /* blue */
}
}
collections {
group {
name: "example_color_class";
max: 500 500;
min: 50 50;
parts {
part {
name: "part_one";
type: RECT;
scale: 1;
description {
state: "default" 0.0;
color: 255 255 255 255;
color_class: "blue_class";
rel1.relative: 0.0 0.0;
rel2.relative: 0.5 0.5;
}
}
part {
name: "part_two";
type: RECT;
description {
state: "default" 0.0;
color: 255 255 255 255;
color_class: "green_class";
rel1.relative: 0.5 0.0;
rel2.relative: 1.0 0.5;
}
}
part {
name: "part_three";
type: RECT;
description {
state: "default" 0.0;
color: 255 255 255 255;
color_class: "red_class";
rel1.relative: 0.0 0.5;
rel2.relative: 1.0 1.0;
}
}
part {
name: "part_four";
type: TEXT;
effect: OUTLINE_SHADOW;
description {
state: "default" 0.0;
min: 50 50;
color: 255 255 255 255;
color2: 255 255 255 255;
color3: 255 255 255 255;
color_class: "blue_class";
rel1.relative: 0.0 0.5;
rel2.relative: 1.0 1.0;
text {
text_class: "example";
font: "arial";
size: 45;
min: 1 1;
ellipsis: -1;
}
}
}
}
}
}

To compile use this command:

* gcc -o edje-color-class edje-color-class.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 color-class.edc
* 
edje_init
int edje_init(void)
Initializes the Edje library.
Definition: edje_main.c:35
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:1059
ecore_evas_shutdown
EAPI int ecore_evas_shutdown(void)
Shuts down the Ecore_Evas system.
Definition: ecore_evas.c:668
edje_color_class_set
Eina_Bool edje_color_class_set(const char *color_class, int r, int g, int b, int a, int r2, int g2, int b2, int a2, int r3, int g3, int b3, int a3)
Sets Edje color class.
Definition: edje_util.c:681
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:1382
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:1160
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:1289
EINA_UNUSED
#define EINA_UNUSED
Definition: eina_types.h:321
ecore_evas_free
EAPI void ecore_evas_free(Ecore_Evas *ee)
Frees an Ecore_Evas.
Definition: ecore_evas.c:1103
edje_color_class_list
Eina_List * edje_color_class_list(void)
Lists color classes.
Definition: edje_util.c:768
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:1547
ecore_evas_init
EAPI int ecore_evas_init(void)
Inits the Ecore_Evas system.
Definition: ecore_evas.c:604
EINA_FALSE
#define EINA_FALSE
Definition: eina_types.h:502
EINA_LIST_FREE
#define EINA_LIST_FREE(list, data)
Definition for the macro to remove each list node while having access to each node's data.
Definition: eina_list.h:1653
edje_color_class_get
Eina_Bool edje_color_class_get(const char *color_class, int *r, int *g, int *b, int *a, int *r2, int *g2, int *b2, int *a2, int *r3, int *g3, int *b3, int *a3)
Gets Edje color class.
Definition: edje_util.c:719
Evas_Object
Efl_Canvas_Object Evas_Object
Definition: Evas_Common.h:180
Edje.h
Edje Graphical Design Library.
Ecore_Evas.h
Evas wrapper functions.
ecore_evas_get
EAPI Evas * ecore_evas_get(const Ecore_Evas *ee)
Gets an Ecore_Evas's Evas.
Definition: ecore_evas.c:1320
_Evas_Event_Mouse_Down::button
int button
Mouse button number that went down (1 - 32)
Definition: Evas_Legacy.h:161
evas_object_event_callback_add
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:489
ecore_main_loop_begin
void ecore_main_loop_begin(void)
Runs the application main loop.
Definition: ecore_main.c:1279
evas_object_show
void evas_object_show(Evas_Object *eo_obj)
Makes the given Evas object visible.
Definition: evas_object_main.c:1853
Evas
Eo Evas
Definition: Evas_Common.h:158
EVAS_CALLBACK_MOUSE_DOWN
Mouse Button Down Event.
Definition: Evas_Common.h:406
EINA_TRUE
#define EINA_TRUE
Definition: eina_types.h:508
edje_color_class_del
void edje_color_class_del(const char *color_class)
Deletes edje color class.
Definition: edje_util.c:745
Eina_Bool
unsigned char Eina_Bool
Definition: eina_types.h:496
evas_object_rectangle_add
Evas_Object * evas_object_rectangle_add(Evas *e)
Adds a rectangle to the given evas.
Definition: evas_object_rectangle.c:78
_Eina_List
Definition: eina_list.h:326
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:1205
ecore_evas_show
EAPI void ecore_evas_show(Ecore_Evas *ee)
Shows an Ecore_Evas' window.
Definition: ecore_evas.c:1500
evas_object_color_set
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:2063
edje_shutdown
int edje_shutdown(void)
Shuts down the Edje library.
Definition: edje_main.c:264
_Evas_Event_Mouse_Down
Mouse button press event.
Definition: Evas_Legacy.h:159