|
|
|
NavigationPersonal tools |
Development with Edje: C API DigestThis website is deprecated!
Please refer and move articles to: http://trac.enlightenment.org/e/wiki/
Since C is the language the Enlightenment Foundation Libraries are actually written in, its he most updated and stable of the available APIs. Since a good API reference already exists, this article is intended only to complement it. You will not find exhaustive analysis of the form but a simple overview of the function along with rationale, notes and "gotchas". I hope that as we review each function, diving straight into the API reference feels like a less daunting task, in fact, reading along you will find that the Edje API is quite small, this is because the main goal with Edje was to keep presentation as separate from logic as practically possible for both developer and designer. Still, we can make the API even easier to learn (and this reference easier to maintain) by separating the available functions into several groups.
[edit] The environment outside the canvasIn the first chapter of the article we set up the canvas wrapper using the most common engine at the time (Software_X11), but the fact is that Evas can be compiled with support for multiple engines, and that this support can be tested at runtime, falling back from one engine to the other if one is not available:
...
Ecore_Evas *ecore_evas;
...
if(ecore_evas_engine_type_supported_get(ECORE_EVAS_ENGINE_GL_X11))
ecore_evas = ecore_evas_gl_x11_new(NULL, 0, 0, 0, 800, 600);
else if(ecore_evas_engine_type_supported_get(ECORE_EVAS_ENGINE_SOFTWARE_X11))
ecore_evas = ecore_evas_software_x11_new(NULL, 0, 0, 0, 800, 600);
else
return EXIT_FAILURE;
...
We could just grab the first example in the article, drop this code and we could make the application powered by OpenGL if it is available, falling back to software or dieing in the worst case. A example of usage can be found in the definition for Once the canvas wrapper is setup there are a couple of additional functions depending on the type. For example, all X11 related engines have functions to control aspects of the windowing environment, like stickiness or resize, while the frame buffer engine does not. The complete list is found (as always) in the API Lists. [edit] The environment inside the canvasTransitions are what makes Edje interfaces become alive. But even then, for reasons like device resources, we need to exert some kind of control over the load in the interface regardless of theme specifics:
...
edje_frametime_set(1.0 / 5.0);
printf("Current frametime: %.0f FPS (Aprox.)", pow(edje_frametime_get(),-1));
edje_freeze();
printf("The whole interface is dead, Jim.");
edje_thaw();
printf("Hold it! it has come back to life.");
...
We begin by reducing the frame time to the measly five FPS that our underpowered device is capable of handling. In order to be sure we got it right we print the current value in the screen. This limitation will be applied to every Edje object rendered in the current process. The last couple of functions will apply [edit] Global style settingsColors and typography might be elements of design but the remain critical to accessibility, the needs might vary from user to user. Manipulating color and text classes are the way for the developer and designer to address those needs, without stepping in each other's toes::
...
Evas_List *color_classes;
Evas_List *text_classes;
Evas_List *e;
printf("Changing button_background to color: red, text outline: green, text shadow: blue. \n");
edje_color_class_set("button_background",255,0,0,255,0,255,0,255,0,0,255,255);
color_classes = = edje_color_class_list();
printf("List of color classes:\n");
for (e = color_classes; e; e = e->next)
printf("S: %s \n",e->data);
printf("Deleting button_background color class. \n");
edje_color_class_del("button_background");
printf("If I delete this text_class it will use the default values. \n");
edje_text_class_del("titlebar");
printf("Oh god! the defaults are so horrible... better set it back. \n");;
edje_text_class_set("titlebar","Sans",24);
text_classes = = edje_text_class_list();
printf("List of text classes: \n");
for (e = text_classes; e; e = e->next)
printf("%s \n",e->data);
...
As usual, the former functions where pretty much self explanatory. When a theme file is loaded into memory Edje will try to use the text and color classes defined by the application, if none are found it will fall back to the default values set by the theme and in the worst case fallback to the default values set by the library. [edit] Data file structureSometimes it is useful to extract information from a theme file before trying
to load the theme itself. Among the functions available we find the
In a parallel world were this function does not exists we could implement similar functionality with other functions in the same group:
...
//Equivalent of edje_file_group_exists("path/to/file.edj","test")
Evas_List *entries, *e;
entries = edje_file_collection_list("path/to/file.edj");
if (entries) {
for (e = entries; e; e = e->next) {
if(strcmp(e->data, "test") == 0) {
edje_file_collection_list_free(entries);
return 1;
}
}
}
edje_file_collection_list_free(entries);
return 0;
...
In the first line we can see a new data structure Evas_List (a specially formated linked list) along with two functions to load and unload the list from memory. The remaining function of this group is [edit] Edje Object inclusionIncluding a new object might seem to be a pretty straightforward process, we get a pointer for the object inside the canvas and we load the object from the theme file to it, but is not error free, thankfully control and diagnostic functions are included in the API as well.
...
const char *file = "path/to/file.edj";
const char *group = "group name";
const char *test_file = "";
const char *test_group = "";
Evas_Object *my_edje_object;
my_edje_object = edje_object_add(canvas);
if(!edje_object_file_set(my_edje_object,file,group)) {
printf("Error Number: %d while loading the theme. \n",edje_object_load_error_get(my_edje_object));
}else{
edje_object_file_get(my_edje_object,&test_file,&test_group);
printf("Group %s successfully loaded from file %s. \n",test_group,test_file);
}
...
The key element here is the Evas_Object pointer, passed as the first parameter
in almost every function with the edje_object prefix. The first setup is to
create the new object in the canvas using Inside the control structure we can see the diagnostic functions. In case of
failure [edit] Edje Object manipulation[edit] Edje Object anatomyEven if the main goal of the library is to separate logic from presentation, this separation was done with space for possible changes, accessibility needs, specially colors, fonts and size constrictions. Colors and font classes work as seen in the "Global style settings" section but
affecting one particular object. That means the functions are prefixed with
edje_object and receive an Edje Object as first parameter. Resulting in the
format Minimal sizes can be a troublesome issue, on one hand we have the size the designer says his theme support through the EDC file, and on the other hand we have the minimal size the object actually supports. The designer can declare a bigger than necessary size for aesthetic reasons but if the declared size is actually smaller, using it could (most probably will) lead to rendering errors:
...
Evas_Coord calculated_minw, calculated_minh;
Evas_Coord declared_minw, declared_minh;
Evas_Object *edje_object = edje_object_add(canvas);
edje_object_size_min_calc(edje_object,
&calculated_minw,
&calculated_minh);
edje_object_size_min_get(edje_object,
&declared_minw,
&declared_minh);
if (calculated_minw > declared_minw || calculated_minh > declared_minh) {
printf("Bad designer!, your theme does not fit within the minimal size you said it would\n" \
"I changed the minimal size to the calculated size, just in case...\n");
edje_extern_object_min_size_set(edje,calculated_minw,calculated_minh);
}
...
Thankfully, neither the maximal size or the aspect relationship between width and height can cause this issue:
...
Evas_Coord maxw,maxh;
Evas_Object *edje_object;
edje_object_size_max_get(edje_object,&maxw,&maxh);
printf("The max width is: %d and the max height is: %d \n",maxw,maxh);
maxw = 200
maxh = 300
edje_extern_object_max_size_set(edje_object,maxw,maxh);
printf("Now it is %d and %s",maxw,maxh)
edje_extern_object_aspect_set(edje_object,EDJE_ASPECT_CONTROL_VERTICAL,maxw,maxh);
printf("The object will maintain a height proportional to %d on resize.",maxh);
...
It should be noted that any attribute altered through the API are applied to the object residing in memory and won't be saved on the actual theme file, hence the extern addition to the prefix. |