Location example with C++ Binding

This example shows how to integrate the Elocation.h library with elementary.

The first part consists of including the headers. In this case we need to include both Elementary C++ binding and Elocation,

#include <Elementary.hh>
#ifdef ELM_ELOCATION
#include <Elocation.h>
#endif

Attention
All necessary libraries from Elementary, Elightenment, C and/or C++ headers should be include here.

Before our main code, we need a set of callbacks to react on incoming elocation events. They are standard ecore events and we register callbacks on these events in the main function.

static void
_print_position(Elocation_Position *position, ::elm::label label)
{
char buffer[1024];
if (!position) return;
snprintf(buffer, sizeof(buffer),
"<b>GeoClue position reply with data from timestamp</b> %i<br/>"
"<b>Latitude:</b> %f<br/>"
"<b>Longitude:</b> %f<br/>"
"<b>Altitude:</b> %f<br/>"
"<b>Accuracy level:</b> %i<br/>"
"<b>Accuracy horizontal:</b> %f<br/>"
"<b>Accuracy vertical:</b> %f",
position->timestamp, position->latitude, position->longitude,
position->altitude, position->accur->level,
position->accur->horizontal, position->accur->vertical);
label.text_set("elm.text", buffer);
}
static Eina_Bool
_position_changed(void *data, int ev_type, void *event)
{
Elocation_Position *position;
position = static_cast<Elocation_Position*>(event);
_print_position(position, *static_cast<::elm::label*>(data));
return ECORE_CALLBACK_DONE;
}

Now we need to actually start the code and initializing pointers for address, addr_geocode, position and pos_geocode and an integer status. We also run a check for elm_need_elocation.

EAPI_MAIN int
elm_main(int argc, char *argv[])
{
#ifdef ELM_ELOCATION
Elocation_Address *address;
Elocation_Position *position;
#endif
if (elm_need_elocation() == false)
return -1;

Now let's set the elm_policy, which defines for a given policy group/identifier a new policy's value, respectively. In this example the only policy we need to set a value for is ELM_POLICY_QUIT, possibles values for it are:

elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_HIDDEN);

As you can see, the policy we chose was to quit when the last win is hidden as opose to examples with the C bindings where we perpetually set it to quit when last win was closed. This changed was necessary because in C++ binding as the elm mainloop stop running all object are destroyed, references are unreferenced and events are stopped at ELM_MAIN().

See also
For more details consult elm_policy_set

Next step is creating an elementary window, in this example we use the C++ binding method with the elm_win_util_standard_add that is a elm_win_legacy function, better explained below. And then we set the autohide state for it.

elm_win_util_standard_add (const char *name, const char *tittle) Adds a window object with standard setup. Parameters:

This creates a window but also puts in a standard background with elm_bg_add(), as well as setting the window title to title. The window type created is of type ELM_WIN_BASIC, with the NULL as the parent widget. Returns the created object or NULL on failure.

The autohide works similarly to autodel, automatically handling "delete,request" signals when set to true, with the difference that it will hide the window, instead of destroying it.

It is specially designed to work together with ELM_POLICY_QUIT_LAST_WINDOW_HIDDEN which allows exiting Elementary's main loop when all the windows are hidden.

::elm::win win(elm_win_util_standard_add("elocation", "Elocation example"));
win.autohide_set(true);

Note
autodel and autohide are not mutually exclusive. The window will be destructed if both autodel and autohide is set to EINA_TRUE or true.

For this example we're using a label that will display the text "Getting location ...". First we'll create our label, setting it's parent, then setting the following label's options:

@ skipline wrap

label.text_set("elm.text", "Getting location ...");

ELM_LABEL_SLIDE_MODE_NONE - no slide effect

ELM_LABEL_SLIDE_MODE_AUTO - slide only if the label area is bigger than the text width length

ELM_LABEL_SLIDE_MODE_ALWAYS -slide always

Attention
ELM_LABEL_SLIDE_MODE_AUTO, ELM_LABEL_SLIDE_MODE_ALWAYS only work with the themes "slide_short", "slide_long" and "slide_bounce". ELM_LABEL_SLIDE_MODE_AUTO, ELM_LABEL_SLIDE_MODE_ALWAYS don't work if the line wrap(elm_label_line_wrap_set()) or ellipsis(elm_label_ellipsis_set()) is set.

label.slide_mode_set(ELM_LABEL_SLIDE_MODE_ALWAYS);

To better understand, the function size_hint_weight_set for C++ bindings originated from C bindings function evas_object_size_hint_weight_set, that is EFL Evas type function. With this function we set the hints for an object's weight. The parameters are:

This is not a size enforcement in any way, it's just a hint that should be used whenever appropriate. This is a hint on how a container object should resize a given child within its area.

Containers may adhere to the simpler logic of just expanding the child object's dimensions to fit its own (see the EVAS_HINT_EXPAND helper weight macro in the EFL Evas Documentation) or the complete one of taking each child's weight hint as real weights to how much of its size to allocate for them in each axis. A container is supposed to, after normalizing the weights of its children (with weight hints), distribute the space it has to layout them by those factors – most weighted children get larger in this process than the least ones.

label.size_hint_weight_set(EVAS_HINT_EXPAND, 0.0);

Note
Default weight hint values are 0.0, for both axis.

The function size_hint_align_set for C++ bindings originated from C bindings function evas_object_size_hint_align_set, that is EFL Evas type function. With this function we set the hints for an object's alignment. The parameters are:

These are hints on how to align an object inside the boundaries of a container/manager. Accepted values are in the 0.0 to 1.0 range, with the special value EVAS_HINT_FILL used to specify "justify" or "fill" by some users. In this case, maximum size hints should be enforced with higher priority, if they are set. Also, any padding hint set on objects should add up to the alignment space on the final scene composition.

For the horizontal component, 0.0 means to the left, 1.0 means to the right. Analogously, for the vertical component, 0.0 to the top, 1.0 means to the bottom.

This is not a size enforcement in any way, it's just a hint that should be used whenever appropriate.

Note
Default alignment hint values are 0.5, for both axis.

label.size_hint_align_set(EVAS_HINT_FILL, EVAS_HINT_FILL);

Setting the size for label and make it visible.

Going back to our elocation, first we'll create an address and position object that we'll use for all our operations.

We also have to register our callback so we get updates later on.

Now we need to get the elocation position and print it, using our label. This fills in the object with the data from GeoClue.

Now we only have to set the size for our window and make it visible.

And finally, start the elm mainloop, starting to handle events and drawing operations.

The full code for this example can be found at location_cxx_example_01.cc