Edje as Logic and Appearance separator

So after reading the previous chapter you have a (mostly blurred) idea of the contents of an .edc file. This file describes your graphical user interface in Edje. It may contain relative positions of objects, some simple animations and maybe some images. But what do you do when you write it?

If you are an experienced programmer you will probably visualize two workflows for .edc files. The static and the dynamic one.

The static approach is the most trivial one. You assume that Edje code segments are just special macros (in C). You include in your C code the "Edje.h" header file which contains the implementation of these macros and you compile your program normally as any other C application. This results into a big executable which includes everything. Both the user interface and the application logic are in one file. See the following figure.

Figure 4.6. Building the UI statically in the application.

Building the UI statically in the application.

This approach clearly helps the developer. Instead of writing lots of C code for Evas she can quickly describe what she want to do in Edje, and be more productive because of abstraction. For a user however things remain unchanged. A single executable is the whole application. Nothing can be changed without the source code. The great benefits of this approach are of course simplicity (no extra tools, just macros and the compiler) and speed (everything is compiled in the end).

The dynamic approach would be to separate the graphical representation of the application from the actual functionality[2]. So you distribute two files for your application. The binary executable which is the code and the text .edc file which describes the interface. The application binary runs and dynamically during runtime it loads the graphical user interface described in the .edc file. This idea already exists for applications but the text file is mostly written in XML so that it is more human readable.

The dynamic approach has a clear advantage regarding flexibility. The user can change the text file representing the graphics of the application and after she runs it for a second time the application adapts to the changes. No recompiling is necessary. See the following figure. A lot of theme frameworks also depend on this technique. The obvious drawback of this is lack of speed. The binary file of the application must contain a text parser for reading the text file which has the application appearance. In the case of XML a full featured XML parser needs to be included. There are separate libraries in the Open Source community which implement XML parsers and thus free the programmer from this burden, but the fact remains that this is added complexity with controversial benefits. It is also clear that while this approach is more convenient for the user, it means more effort for the programmer in order to accomplish the required flexibility.

Figure 4.7. Loading the UI dynamically in the application.

Loading the UI dynamically in the application.

With Edje you don't have to choose between the two approaches (static, dynamic). The Edje approach is a third one which combines the best of both worlds and does away with the disadvantages! The following table summarizes the Edje approach:

Table 4.2. The Edje Appearance/Logic separation

 Static wayDynamic wayEdje way
Files Distributed1 binary1 binary + 1 text2 binaries
UI residesInside main executableIn separate text fileIn separate binary file
SpeedFastSlowFast
UI codecompiled (built-in)text (interpreted)compiled (loaded)
UI is determinedDuring compile timeDuring run timeDuring run time
UI FlexibilityNoYesYes

In Edje the .edc text file is compiled into a .edj file via the edje_cc compiler which is offered along the Edje framework. The resulting .edj which is binary is loaded during run-time into the main executable resulting into the final application which is presented to the user. See the following figure. You should see now why the solution combines the advantages of both approaches. You have a binary file with your UI (fast) that is added dynamically (flexibly) into your application. We are not aware of any other technology in the Open source world which does the same thing.

Figure 4.8. Separation of GUI and code in Edje.

Separation of GUI and code in Edje.

You may think that the figures presented so far at too high level and do not actually explain how all this is accomplished. A great number of programmers want to get down and dirty with code to really understand a concept. Rather than presenting long code listings with an Edje application we will describe things a bit more concisely. So let's say that you have been enlightened with Edje and want to write your next application with it. What do you actually do?

First you write your .edc file which contains the User interface. Then you write the C code of your application. The C code would only contain initialization of a Canvas and nothing more (more on this later). When the UI is initialized you designate the name of the .edj (compiled Edje UI) that is to be loaded. This should be something like edje_file_load("my_UI.edj"). The name of the function does not really matter. Currently Edje is just a normal Canvas Object. You create and put it in a Canvas like any other object. The name of the associated .edj file is a property of the Edje object.

Next you rename your UI text file to my_UI.edc. You compile it with edje_cc and the resulting file is a binary one named my_UI.edj. The end user installs the binary and the .edj file (probably somewhere in /usr/share). When the application runs it dynamically loads the my_UI.edj file and draws itself of screen. If another my_UI.edj file replaces the previous one, the application will use this instead (themes anyone?).

It is rather simple actually. The only thing left to explain is how communication is handled between the UI placed into Edje and the C code of the application. No mystery here. If you already know to how to use GTK+ callbacks or QT Signals/Slots you are already set.

In the programs part of an .edc file you can define apart from animation (as shown previously) signals that are emitted from the User Interface in Edje back to the main C code of your application in response to user events. In your .edc file you would include in the programs block code like this:

Example 4.5. Sending a signal from Edje to C code.

program 
{ 
	name, "user_clicked_button"; 
	signal, "mouse,down,*"; 
	source, "ok_button"; 
	action, SIGNAL_EMIT "finished" "ok"; 
} 

This should be easy to understand. The asterisk in the signal like denotes any mouse button. So this program would run when the user clicks (mouse down) on the source component (named "ok_button). The finished and ok parameters are additional options which are passed back to C code. Since an OK button has only one function (usually) these extra options are not needed but are just shown here for educational purposes.

That is all that you have to do in the .edc file of your application. To decide what happens when these signals are emitted you write in the C code function callbacks which register which signals they want to listen to. As you might expect we will not show any API for this but you can rest assured that is just normal C code and nothing extraordinary. The Edje API provides you also with functions which can change the Edje User Interface programmatically. Thus, you are given the ability to respond to Edje signals with changes in the Edje object itself.[3]

So in the end you have an application binary full of functionality (C functions) and an .edj file which contains the User Interface. These two communicate dynamically while the application runs. A media player as a full example is described in the Edje book. You should consult it if you want to see in detail how a media player would work the Edje way. All the functionality for music files (load, play, stop, pause) are in C code, while everything that is graphical (stop, play buttons e.t.c) are in the Edje object.

After reading this section you may probably think that Edje would be a good framework for themes. You are right of course! Edje was built with theming in mind and we devote a separate section for this Edje ability.



[2] You should be already familiar with this concept if you have ever done web programming where XHTML/CSS and Server Side Code are all contained in different files

[3] Not to be confused with introspection