Elementary is a widget toolkit and EFL wrapper and convenience library to make it easy to build applications and tools with UI's with less code, as well as being able to still dig down layers. Let's begin with a hello world example. This assumes you have managed to install Elementary by now and are wondering where to get started with using it.

To compile the following example, just copy and paste it into your favorite text editor and save it as 'hello.c'. Then run the following command:

gcc hello.c -o hello `pkg-config elementary --cflags --libs`

Now this may seem a little long, but it is fully commented and does more than just say "Hello world". It can interact with the user allowing them to close the window (and respond by quitting) or by pressing OK (which results in the same action). This style of programming is called event-driven programming. The application doesn't sit and loop continually itself "doing things" like the first simple C programs you may have learned. It only does some setup and then lets the toolkit (Elementary) do the "looping" for it. IT is important to get this big difference in programmming model as most toolkits do exactly this. It is more efficient to do it this way and saves the programmer lots of time in the long run when done this way. In this case Elementary will sleep and wait on input and other timing events, and based on that input, it will call the functions that it is told to - thus the need for adding the callbacks.

Callbacks are a construct where a function is registered with some system, so that it can be called "on demand" by that system. In this case when the events indicate OK has been clicked OR when the window close button is pressed.

#include <Elementary.h>staticvoidon_done(void*data,Evas_Object*obj,void*event_info){/* quit the mainloop (elm_run) */elm_exit();}EAPIintelm_main(intargc,char**argv){Evas_Object*win,*bg,*box,*lab,*btn;/* new window - do the usual and give it a name, title and delete handler */win=elm_win_add(NULL,"hello",ELM_WIN_BASIC);elm_win_title_set(win,"Hello");/* when the user clicks "close" on a window there is a request to delete */evas_object_smart_callback_add(win,"delete,request",on_done,NULL);/* add a standard bg */bg=elm_bg_add(win);/* not allow bg to expand. let's limit dialog size to contents */evas_object_size_hint_weight_set(bg,0.0,0.0);/* add object as a resize object for the window (controls window minimum * size as well as gets resized if window is resized) */elm_win_resize_object_add(win,bg);evas_object_show(bg);/* add a box object - default is vertical. a box holds children in a row, * either horizontally or vertically. nothing more. */box=elm_box_add(win);/* make the box hotizontal */elm_box_horizontal_set(box,EINA_TRUE);/* not not allow box to expand. let's limit dialog size to contents */evas_object_size_hint_weight_set(box,0.0,0.0);/* add object as a resize object for the window (controls window minimum * size as well as gets resized if window is resized) */elm_win_resize_object_add(win,box);evas_object_show(box);/* add a label widget, set the text and put it in the pad frame */lab=elm_label_add(win);/* set text of the label */elm_object_text_set(lab,"Hello out there world!");/* do not allow label to expand */evas_object_size_hint_weight_set(lab,0.0,0.0);/* pack the label at the end of the box */elm_box_pack_end(box,lab);evas_object_show(lab);/* add an ok button */btn=elm_button_add(win);/* se label for button to "OK" */elm_object_text_set(btn,"OK");/* do not allow button to expand */evas_object_size_hint_weight_set(btn,0.0,0.0);/* pack the button at the end of the box */elm_box_pack_end(box,btn);evas_object_show(btn);/* call on_don when button is clicked */evas_object_smart_callback_add(btn,"clicked",on_done,NULL);/* now we are done, show the window */evas_object_show(win);/* run the mainloop and process events and callbacks */elm_run();return0;}ELM_MAIN()

Elementary

Elementary is a widget set. It is a new-style of widget set much more canvas object based than anything else. Why not ETK? Why not EWL? Well they both tend to veer away from the core of Evas, Ecore and Edje a lot to build their own worlds. Also I wanted something focused on embedded devices - specifically small touchscreens. Unlike GTK+ and Qt, 75% of the "widget set" is already embodied in a common core - Ecore, Edje, Evas etc. So this fine-grained library splitting means all of this is shared, just a new widget "personality" is on top. And that is... Elementary, my dear watson. Elementary.

Candy

The first thing people want to know is, what does it look like. Yes Yes. Let's get on with it. Here's the Candy.

Those are just some of the widgets in the test application. There is more to this, with widgets animating in some cases as well as having multiple styles. Here are a few real-life application screenshots:

Elementary comes, out of the box, able to support ARGB windows - as well as shaped windows. That means for fancy windowing and interface ideas with compositors are supported out-of-the-box. note the difference with the same logo icon here. The first is shaped, giving it a "jagged" monochromatic shape. The second is smooth with an alpha channel. Same identical application code. Elementary handles detecting if a compositor exists and creating the window appropriately, or using shaped windows if not:

This is why the window background is actually a separate widget. You may not want one and thus - don't put one there. You may want multiple backgrounds and layer them, or use the layout widget and an edje design that scales nicely, or anything else. Widgets are just objects you can stack (raise/lower) etc. within the canvas that is in the window widget.

Elementary also scales - and can do so given a scaling factor. this is set on the root window or overridden with an environment variable. This can be manually set by a user or calculated from DPI, but the main point is that it scales given a value OTHER than directly looking at DPI (which is a bad way to scale - a 52" HDTV has a relatively low DPI - so you don't go scale everything down to be tiny, because you watch it from the other side of the room. Some small high-DPI screen on phones you hold close to your face - not the distance a normal computer screen would be at, so you generally don't scale up as much. So everyone runs around modifying the DPI just to have universal scaling factors - which is really wrong). That is why you want another scaling factor to use. Here are some examples of the same application - same UI, just with different scaling factors:

Note how it scales - but only the "important things" scale. Those that should. Things that should stay "pixel-perfect" like the hilights, shading, textures and decorations etc. - stay just as they should. Pixel-perfect. It'd be nice if every widget set were to respect such root properties and/or environment variables instead of looking at DPI. Then just a simple tool to set the variable or root property (based on DPI or on anything else the user likes) would do the same job - but stop people from messing about with DPI.

Now the above only vary scaling factor. Even if you scale up for reading - you want interaction to have a different scaling factor. how accurate is the mouse, stylus.. or finger? You want to force "hit areas" to be big for a fuzzy finger. The below show the UI above at scale 1.0 and 2.0 but with varying larger finger sizes - allowing for easier hitting on touchscreens with a finger:

List me up!

And now that candy time is over, it's time to begin some more in-depth information. Elementary is small. it's API currently is not incredibly extensive, but it's usable. It's written in C and it's API is C. It's clean and consistent and should be easy to pick up just by reading the Elementary.h header installed and some example code. It is primarily developed for X11, but also runs in the Framebuffer (limit of 1 window of course) and has had some work done for a WinCE port. Under X11 you can use Software, XRender or OpenGL to draw. Elementary also supports scalable interfaces (scale to a scaling factor that can be calculated from DPI for example) as well as alpha channels and compositing for windows. Of course it's look is entirely defined in a theme by Edje, so changing the look is possible, and very powerful and flexible.

So you have an idea of what things Elementary does on a broader sense, here is a quick list of the widgets and what they do:

Widget

Description

Win

This is the basic window widget. It handles all setup and the glue of the windowing system (if any) and the canvas abstraction. It also provides sub-windows (Inwin's) inside the window intended for quick popups of information that may normally use a separate window, but you don't want to here.

Bg

Background handling. As elementary does support transparent (shaped or translucent if you have a compositor) windows, the window background is actually a separate widget you can put in a window if you want a background. This gives you a standard theme defined background OR allows you to also put in a custom image for a window background too.

Icon

A standard icon that may be provided by the theme (delete, edit, arrows etc.) or a custom file (PNG, JPG, EDJE etc.) used for an icon. The Icon may scale or not and of course... support alpha channels.

Box

A box packing widget. Pack into a horizontal or vertical box.

Button

A push-button. Press it and run some function. It can contain a simple label and icon object.

Scroller

This allows the contents to be scrolled around. By default it has "finger scrolling" working with momentum, given that the focus of Elementary is gadgets.

Label

Display text, with simple html-like markup. The theme of course can invent new markup tags and style them any way it likes.

Toggle

Looks very iPhone-like - a toggle button you have to drag left/right like a real sliding toggle-switch to toggle between 2 states.

Frame

Holds some content and has a title. Looks like a "frame", but supports styles so multiple frames are available.

Table

arranges widgets in a table where items can also span multiple columns or rows - even overlap (and then be raised or lowered accordingly to adjust stacking if they do overlap).

Clock

For displaying time and setting it.

Layout

This takes a standard Edje design file and wraps it very thinly in a widget and handles swallowing widgets into swallow regions in the Edje object, allowing Edje to be used as a design and layout tool.

Hover

This makes a widget hover over another (tracking its location and size wherever it goes). This is a core that is meant for popping up temporary things over something else. It supports multiple styles and is used in other widgets.

Entry

For entering text in a single or multiple lined way, passwords, copy and paste, etc.

Notepad

A higher level widget that puts together a scroller, entry and some other code to read and write text files. This automatically will load a text file and put it in the notepad, and save it whenever it is modified back to that file. Makes writign a notepad app a breeze.

Anchorview

For viewing text that has anchors (links) in the markup within a scrollable region, and for popping up menus (using Hover) when the anchors are clicked (really handy for doing quick displays of test like messages and having names, numbers and URL's hilighted and ready to click to access)

Anchorblock

Same as Anchorview, but just not scrollable. Intended for putting inside something more complex

Bubble

A lot like the Frame widget, but with a title, note and icon region. Can support multiple directions from which the "speech bubble" comes from. Intended for displaying messages (short ones) to look like some form of speech.

Photo

For displaying the photo of a person (contact). Simple yet with a very specific purpose.

Hoversel

Much like a combobox - when you press the button a list of options slides open to select from - with icons and labels for all. When one is selected it goes away again (or when somewhere else is pressed it is canceled).

Toolbar

For listing a selection of items in a list within a "bar", each item having an icon and label. This is more or less intended for use when selecting different modes - much like a tab widget, but this is just the bar piece.

List

A vertical list of items. Intended for smallish lists (maybe 100 or 200 items at most - the more you have the slower it will get). It can include arbitrary widgets packed to the left/right of a label as well as optionally compress the text of the label to fit the list width. Also includes the scroller for making it scrollable. Supports single and multiple selections.

Carousel

Not finished yet. Will be a carousel-like selector.

Slider

A slider bar to select a value along a range with 4 directions supported, value indicator, unit indicator, icon and label.

Genlist

Not finished yet. Generic list. More work to use that List, but able to hold many more items with much more flexible layouts etc.

Back to the Future

Of course the list above isn't everything. "Where's the file selector?". "What about a range slider?", "Radio buttons?"... Well you have come to the right place. There *IS* a list of things to add/do to Elementary. Look at Elementary.h - it's kept at the bottom (so you know what you're missing... for now). For now I'll list some of these here:

full window in window widget (so move/resize of window object does as you'd expect a child window to do within the canvas)

4. Improvements - low priority

need another sample theme

need a way to set a preferred size of a widget (but not min or max).

merge with gurana

use evas's new box instead of a box smart

use evas's table instead of a table smart

use stack for win widget

prepend or append theme files from code for an app to allow an app to augment the theme eithe rby forcibly overriding things with its own theme file (so it can ship some custom elements that always override user theme) and so it can also provide a final (even after default) fallback for "extended" styles of its own (but thus allowing themes to overried its extensions if they want)

determine prefix of app dynamically and export calls to get prefix info

load config from file

load config from x property

handle finger size property and on-the-fly changes like scaling does

somehow a pdf(ps) viewer widget that doesnt make it gpl (lgpl)

emotion widget

ewebkit widget

flash (gnash) widget

need url and path entry modes for vkbd

return list of toplevel window objects

focus should have an object that is layered above all others (definable layer) that moves + resizes (slides about - animated) from one focused widget to the next for focus. also emit focus/unfocus signals too

scroller could do with page up/down/left/right buttons and and idea of a page size

current sizing tree inefficient

need a way to filter entry data for entry (eg for phone numbers)

win should emit signals based on vkbd type - if it gets a message and is a vkbd win

win needs a way of setting aspect too

use the wrong call on the wrong widget and *BOOM* ... crashland

Getting the basics

"So how do I get my grubby hands on this natural wonder you call Elementary" you may ask. Well right now the best way is to get it from SVN. I won't go into details on how to get EFL set up - there's plenty of information elsewhere on that (and if you're reading this I will assume you already have been looking at the rest of EFL. If someone wants they can add links here), so I'll just tell you about elementary:

svn co http://svn.enlightenment.org/svn/e/trunk/elementary

And just like everything else in EFL:

cdelementary./autogen.shmakesudomakeinstall

In the src/bin directory is test.c - this is the source for the elementary_test application - run this to see it working. Read the code if you want deeper insight into how Elementary is being used - there's even some comments.

And same build procedure as above, with similar binary names. Source is in src/bin.

Hello World

Now you have an idea of what can be done, we will get you started on your first application. Of course this will be the ubiquitous "Hello World" application. Don't be scared. It's in C. It's not hard. Just read the code below (without comments to show how compact it can be). This is what the application will look like when it runs:

Now you may say "my god that's a lot of code for hello world!". Yes - it is. We can play games of "smallest hello world app" but Elementary is designed for longer-term usability. So it's a little extra work to get started, but not much. The benefits will pay off in the long run. I will now explain how the code above gets written, piece by piece.

This is how you will begin your Elementary using application. The #include line includes all the relevant EFL headers you need, as well as a host of standard system headers to save you time, effort or the need to know just what to include to do C. This gets you started. Then comes the main function of your application. It MUST be called elm_main. This is a special function and is used by Elementary to start applications faster. You must NOT do ANYTHING in your application before this function is called, except initialize elementary. The ELM_MAIN() macro above is an initial template piece of code provided for you in the Elementary.h header that sets up your application's main() function, initialized Elementary and immediately calls elm_main() with your arguments. The above is pretty much boiler-plate code and how you will start all your applications.

Note that the elm_main function just starts the elm main loop with elm_run. This function will not return as long as the main loop runs (that handles incoming events from keyboards, mice, touchscreens, other applications etc.). Once the main loop stops running, elm_run will return and go onto the next function - in this case elm_shutdown to shut down elementary and anything it wants/needs to clean up. The return after this simply returns the exit/error code for the application. 0 means everything is ok. Any other value means something bad happened - an error of some sort.

Now inside elm_main we add some code to create a window, hook a callback to it (a callback is a function that is run for you when a specific event/situation occurs), define the callback and show the window. The window of course will be minuscule in size and have no content. But we need to start somewhere. So we create the window with elm_win_add. The first parameter is NULL as we have no window to associate this one with - it's our first (and only) window. The next parameter is the "name" of the window. This should be unique among all the windows in the application - every type of window should have a unique name of its own. Then the type of the window (ELM_WIN_BASIC - a basic normal window). Then we set the window title with elm_win_title_set to "Hello". Now comes the callback. We attach a callback to the window when the "delete-request" signal happens. This happens when someone presses the close button on your window. We do want the window to close and the application to exit when this happens, don't we? The reason it doesn't automatically end the application is because you may have multiple windows up, and may want to allow the closure of 1 and keep the application running. There is a mechanism in Elementary to have it automatically close (delete) the window for you when this happens. Use elm_win_autodel_set to enable this. Above, when the close button is pressed (or any other mechanism that is used for closing windows is activated), the win_del function will be called. In this function note that we do only 1 thing. We call elm_exit. This exits the main loop, returning control to the elm_main function just after elm_run.

Generally speaking, if you have anything your application wants to or needs to clean up before it exits, put it after elm_run (and before elm_shutdown). Conversely, anything your application needs to do on start - load files, configuration, create windows, parse parameter on the command-line (argv and argc as per standard C conventions) and other things, do it at the start of elm_main

At the end - the window is shown and thus you can see it when the application runs.

Now we wanted more than a blank window. We want a background. Above we add in the standard background for a window. We create a Bg widget, set the sizing weights (allowing the widget to expand and thus in turn controlling the window it lives in and the window's ability to expand). Then the window is informed that this object is one of the objects that will influence the window's geometry (minimum and maximum size, expansion etc. etc.). The window's constraints are an amalgam of all the objects that are set to be resize objects with elm_win_resize_object_add. Finally the background is shown - so you can see it.

And finally, we add a label widget. Since it is created after the background, it will be on top. Objects are by default create on the top - so newer ones will be above older. You can re-stack using evas_object_raise for example, and other related Evas stacking calls, but here we just create in order from bottom to top to keep it simple. So add the label to the window, set the label text (yes labels support minimal html-like markup so you can use newline <br> tags for example), set the label so it will expand (like the background) so it won't limit the window size, set it as another resize object, and show it. Presto. Your first Elementary application. Pun intended.

Configuration

Right now the only configuration Elementary can use is provided by environment variables, the theme(s) specified (they specify the look and feel, animations, fonts and font sizes etc.) and 1 X property on the root window. Let's go into some of these.

Environment Variables

ELM_DATA_DIR - This variable tells Elementary what directory system data is stored. This is primarily used for one thing currently, and that is finding out where the system themes are stored. This is $ELM_DATA_DIR/themes. Usual values of ELM_DATA_DIR would be /usr/local/share/elementary or /usr/share/elementary. If this variable is not set, Elementary uses the next variable down... ELM_PREFIX

ELM_PREFIX - This variable tells Elementary its install prefix. This would be the same prefix you may use to configure Elementary - example with ./configure --prefix=/my/prefix. Elementary will assume data is in $ELM_PREFIX/share/elementary and otherwise themes are a sub-dir of this as above. If this is not set, Elementary will use the location of libelementary.so, IF the target supports dlopen() and dladdr() calls. So if it finds the library is /usr/local/lib/libelementary.so, then it will assume the PREFIX is 1 directory back from that, i.e. /usr/local and otherwise the rules apply as if you set ELM_PREFIX above. If this isnt' compiled in, for for some reason Elementary doesn't find the data dir correctly, relative to the library, it will fall back to the compiled-in data dir location which is normal for almost all UNIX/Linux apps when they need to find their accompanying data. Why all these variables and funky stuff? Well Elementary is able to be ported to platforms like Windows where software must be able to be located anywhere and so it needs a way to find where it lives. But more importantly - this makes Elementary relocatable after compile-time on Linux and UNIX in general - so if you compiled with --prefix=/opt/whatever - it is possible to rename /opt/whatever to something else, or move it somewhere. As long as the relative directory structure remains intact, it will nicely adapt at runtime. This is actually the kind of support things like Autopackage would like and really should be done everywhere. It takles extra effort by developers, but is worth it.

x11-16 - Software X11 16bpp engine (may have bugs and will be lower quality, but faster)

fb - Software Framebuffer (direct)

gdi - Windows XP software GDI engine.

wince-gdi - Windows CE GDI engine.

ELM_SCALE - This sets the scaling factor, overriding the scaling factor found on the root window property. It should be a float of the format 1.0, 2.0, 0.634 etc.

ELM_THEME - This sets the theme(s) to be used in order from most preferential, to least, just with the theme name (minus the .edj extension) with a : character delimiting the name. A simple personal theme would be mytheme. If you wish to primarily use your personal theme, and then fall back to another, you can do: mytheme:fallback. This allows as many levels as you like. It is always assumed that the final fallback theme is the default theme. A complex example would be: mytheme:fallback:systemfallback:othersystem. Remember theme names like "mytheme" mean it assumes a mytheme.edj is in $HOME/.elementary/themes OR if not found here first, it is in $ELM_DATA_DIR/themes under the same name. Themes in your users theme dir always take precedence. A Theme name can ALSO be a relative or full path to a file. In this case the fill filename including extensions needs to be given. i.e. /path/to/file.edj:mytheme:fallback:../../relative/path/file.edj:./dir/file.edj. With full or relative paths searching in order still happens. Note that there is a convenience shortcut for the users home directory of ~/. So if a theme element is ~/dir/file.edj then ~/ is expanded to the the value of $HOME (the users home directory).

HOME - This is used to find the users home directory - used for finding the users personal collection of theme files in $HOME/.elementary/themes. If it is not set - it will be assumed to be blank.

ELM_FONT_HINTING - This affects the font hinting method used when drawing outline text. Generally Bytecode hinting will give the best results as it tries to align fonts to exact pixel boundaries for best clarify. Automatic hinting tries to hint automatically without bytecode and gets it right mostly, but not always. No hinting turns it off and produces "correct" shapes but they may be blurry.

ELM_FONT_PATH - This sets the path (same as the UNIX PATH variable) as a colon-separated list of directories to look in for fonts, with the directories search in order from first to last. An example path may be something like: "/home/user/fonts:/usr/local/share/fonts:/usr/share/fonts"

ELM_IMAGE_CACHE - This sets the image cache in Kb. The default is 4096Kb. This is used to speculatively hold ARGB image data when it is not references/used anymore just in case its needed again in future.

ELM_FONT_CACHE - This is a number that sets the font cache in Kb. The default is 512Kb. This keeps a certain amount of font glyph rendering data around in case its needed again in future.

ELM_FINGER_SIZE - This is sets the size of a "finger" in pixels. This should be tuned for the intended target and use. If Elementary is being used on a desktop, a finger size of 0 would be right. The same would apply for using on a touchscreen with a stylus. If you use it with an actual finger, then the size would be recommended to be bigger. This adjusts the size and hit area of widgets so they are easy to hit with a finger. The size is in pixels and determines the minimum size of a square on the screen that is reliably hittable with a finger. This varies from device to device, but as an example at 285DPI, a finger size of about 80-100 would be right. Finger size would proportionally lower with DPI (ie ELM_SCALE). The default finger size is 40, and is multiplied by ELM_SCALE. So if ELM_SCALE is set to 2.0, the effective finger size is 80. At a scale of 1.0, the finger size will be 40. If explicitly set with the ELM_FINGER_SIZE parameter, scaling does not affect finger size, so consider these 2 separate parameters. One for display size for reading/viewing, and one for input and interaction.

X Properties

Elementary listens (and reads) 1 specific X property - used for determining the scaling factor for Elementary. If this is set, it should be a property named ENLIGHTENMENT_SCALE set on every root window, and be of type CARDINAL. The value is an integer. 1000 means a scaling factor of 1.0 (i.e. no scaling compared to the theme design font/images). 2000 means a scaling factor of 2.0. 500 means 0.5 and so on. So basically it is scaling factor * 1000 rounded to an integer. If this property changes at runtime, Elementary will re-read it and adjust the scaling of the UI automatically. An example xprop output for the property:

ENLIGHTENMENT_SCALE(CARDINAL) = 1000

Simple Dialog

So now we have some more examples to get your started. This example below is a simple command-line dialog. This will display a window with some given text (the first command-line argument to the dialog app) and with an OK and Cancel button. If the user presses OK, the application returns a success exit code (0) and otherwise, a failure code (-1).

gcc dialog.c -o dialog `pkg-config elementary --cflags --libs`

Then just run it:

./dialog 'This is a dialog with text<br>in it. YAY!'

You could use this in a script to add some GUI interactions. Build a small set of such command-line tools for popping up useful requestors from scripts. For example:

Simple File Selector

So now we get more complicated. This application will use the list widget too and list directories, even let you browse around (to parent directories and into child directories). Pressing OK with a file or directory selected or double-clicking on a file will "select" it and exit the app, printing the selected file path. This also uses other EFL facilities like ecore_file for making file access a bit simpler.

gcc selector.c -o selector `pkg-config elementary --cflags --libs`

Then just run it:

./selector $HOME

And you can browse files in your home directory. If a file is selected, it will be output to stdout. This can be handy in scripts like this to select a file to delete. Beware! It actually DOES delete files. Here you go.: