Button - Complete example

A button is simple, you click on it and something happens. That said, we'll go through an example to show in detail the button API less commonly used.

The first part consists of including the headers. In this case we are only working with the Elementary C++ binding and thus we need only to include him.

#include <Elementary.hh>

Attention
If necessary the C and/or the C++ headers should be include here as well.

Now we need to actually start the code and 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:

EAPI_MAIN int
elm_main(int argc, char *argv[])
{
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.

win.title_set("Button 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.

In this example we'll have several buttons that will be arranged in two boxes that will be inserted in a bigger box. One of the smaller boxes will contain a set of buttons that will set different times for the autorepeat timeouts of the buttons that will be contained in the other smaller box.

For all this to work, we will construct the three smaller boxes and all the button that will be needed. The smaller boxes will be then packed in the bigger one.

In this part we'll create our directional buttons, that we'll be added in the third smaller box, this is necessary for our callback to work properly.

::evas::object icon_still(nullptr);
::elm::button mid(efl::eo::parent = win);
::elm::button up(efl::eo::parent = win);
::elm::button down(efl::eo::parent = win);
::elm::button left(efl::eo::parent = win);
::elm::button right(efl::eo::parent = win);

Now let's create our bigger box using the C++ method and setting it's parent as win.

::elm::box box(efl::eo::parent = win);

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.

box.size_hint_weight_set(EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);

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

Now we add the box as a resize_object to win informing that when the size of the win changes so should the box's size. And finally we make it visible.

Creating our initial box, again using the C++ method, in this case we want the arrangement of the objects, that this box will contain, to be displayed horizontally and fot this we will set horizontal to true, vertical by default.

Again we'll set the size hint for weight, but in this box we will set the packing method to include this box inside the bigger one.

When using the elm box the packing method of the subobj - box in this case - should be defined. There are four possible methods:

In this and most examples we use pack_end by choice and practicality. In this part of the code we also make calendar visible.

Now let's start creating the buttons that will be included in this first small box, this will contain the initial timeout button.

We'll use again the C++ method to create this button, set a text, packing method for btn and finally make it visible.

In this part we'll use Lambda type function that will be added in the clicked callback for all buttons in the first smaller box, that'll identify the current initial and gap to be use in the autorepeat timeout that will move the central button.

Note
To learn more about Lambda Function and its use in Elementary consult Lambda Functions with Elementary - C++11.

The second and third button will also set the initial timeout but with different values.

Now for our gap timeout buttons will create our second smaller box, the same way with the initial box, we'll use the C++ method, set to be horizontal, set the size hint weight, choose the packing method and set the visibility to true.

For our gap buttons we'll again, use the C++ method, set the texts with the different values for gap, choose the packing method, set the visibility and the clicked callback.

Now we'll give our directional buttons more options so that it will visible and also have all the caracteristics that is require.

For the up button, we'll set to true the autorepeat, autorepeat_initial_timeout, autoreapet_gap_timeout, the size hints for weight and alignement, choose our packing method and making out up button visible.

For this directional buttons we'll have a diferent repeated callback that will insure the timeouts of our middle button in the gap and initial timeout that is current setted.

For our second callback, we'll detail the release of our directional buttons.

Finishing our up button, we'll create an icon, that'll will be the standard "arrow_up".

This last box, will content all the directional buttons and the middle button. As before, we use the C++ method, horizontal set, weight and align hints, chose the packing method and make it visible.

Now we'll create all the directional and middle buttons, the same as we did with the up button, changing only the icon.

Now we set the size for the window, making it visible in the end:

Finally we just have to start the elm mainloop, starting to handle events and drawing operations.

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

This example will look like this:

button_cxx_example_01.png