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:1065
edje_object_color_class_del
void edje_object_color_class_del(Evas_Object *obj, const char *color_class)
Delete the object color class.
Definition: edje_util.c:978
ecore_evas_shutdown
EAPI int ecore_evas_shutdown(void)
Shuts down the Ecore_Evas system.
Definition: ecore_evas.c:674
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_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:696
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:1388
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:1166
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:1308
EINA_UNUSED
#define EINA_UNUSED
Definition: eina_types.h:339
ecore_evas_free
EAPI void ecore_evas_free(Ecore_Evas *ee)
Frees an Ecore_Evas.
Definition: ecore_evas.c:1109
edje_color_class_list
Eina_List * edje_color_class_list(void)
Lists color classes.
Definition: edje_util.c:783
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:1553
ecore_evas_init
EAPI int ecore_evas_init(void)
Inits the Ecore_Evas system.
Definition: ecore_evas.c:606
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
EINA_FALSE
#define EINA_FALSE
Definition: eina_types.h:533
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:1629
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:734
Evas_Object
Efl_Canvas_Object Evas_Object
Definition: Evas_Common.h:185
evas_object_resize
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
Edje.h
Edje Graphical Design Library.
edje_object_color_class_set
Eina_Bool edje_object_color_class_set(Evas_Object *obj, 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 the object color class.
Definition: edje_util.c:892
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:1326
edje_object_add
Evas_Object * edje_object_add(Evas *evas)
Instantiates a new Edje object.
Definition: edje_smart.c:22
_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:478
ecore_main_loop_begin
void ecore_main_loop_begin(void)
Runs the application main loop.
Definition: ecore_main.c:1298
evas_object_show
void evas_object_show(Evas_Object *eo_obj)
Makes the given Evas object visible.
Definition: evas_object_main.c:1814
edje_object_part_text_set
Eina_Bool edje_object_part_text_set(const Evas_Object *obj, const char *part, const char *text)
Sets a given text to an Edje object TEXT or TEXTBLOCK parts.
Definition: edje_util.c:6722
Evas
Eo Evas
Definition: Evas_Common.h:163
EVAS_CALLBACK_MOUSE_DOWN
@ EVAS_CALLBACK_MOUSE_DOWN
Mouse Button Down Event.
Definition: Evas_Common.h:422
EINA_TRUE
#define EINA_TRUE
Definition: eina_types.h:539
edje_color_class_del
void edje_color_class_del(const char *color_class)
Deletes edje color class.
Definition: edje_util.c:760
Eina_Bool
unsigned char Eina_Bool
Definition: eina_types.h:527
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:317
evas_object_move
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
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:1211
ecore_evas_show
EAPI void ecore_evas_show(Ecore_Evas *ee)
Shows an Ecore_Evas' window.
Definition: ecore_evas.c:1506
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:2024
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