Tizen Native API  6.5
Box - Layout transitions

Setting a customized layout for a box is simple once you have the layout function, which is just like the layout function for Evas_Box. The new and fancier thing we can do with Elementary is animate the transition from one layout to the next. We'll see now how to do that through a simple example, while also taking a look at some of the API that was left untouched in our previous example.

#include <Elementary.h>

Our application data consists of a list of layout functions, given by transitions. We'll be animating through them throughout the entire run. The box with the stuff to move around and the last layout that was set to make things easier in the code.

typedef struct
{
   Eina_List *transitions;
   Evas_Object *box;
   Evas_Object_Box_Layout last_layout;
} Transitions_Data;

The box starts with three buttons, clicking on any of them will take it out of the box without deleting the object. There are also two more buttons outside, one to add an object to the box and the other to clear it. This is all to show how you can interact with the items in the box, add things and even remove them, while the transitions occur.

One of the callback we'll be using creates a new button, asks the box for the list of its children and if it's not empty, we add the new object after the first one, otherwise just place at the end as it will not make any difference.

static void
_add_cb(void *data, Evas_Object *obj EINA_UNUSED, void *ev EINA_UNUSED)
{
   Evas_Object *btn;
   Eina_List *children;
   Transitions_Data *tdata = data;

   btn = elm_button_add(tdata->box);
   elm_object_text_set(btn, "I do nothing");
   children = (Eina_List *)elm_box_children_get(tdata->box);
   if (children)
     {
        elm_box_pack_after(tdata->box, btn, (Evas_Object *)children->data);
        eina_list_free(children);
     }
   else
     elm_box_pack_end(tdata->box, btn);
   evas_object_show(btn);
}

The clear button is even simpler. Everything in the box will be deleted, leaving it empty and ready to fill it up with more stuff.

static void
_clear_cb(void *data, Evas_Object *obj EINA_UNUSED, void *ev EINA_UNUSED)
{
   Transitions_Data *tdata = data;
   elm_box_clear(tdata->box);
}

And a little function to remove buttons from the box without deleting them. This one is set for the clicked callback of the original buttons, unpacking them when clicked and placing it somewhere in the screen where they will not disturb. Once we do this, the box no longer has any control of it, so it will be left untouched until the program ends.

static void
_unpack_cb(void *data, Evas_Object *obj, void *ev EINA_UNUSED)
{
   Transitions_Data *tdata = data;
   elm_box_unpack(tdata->box, obj);
   evas_object_move(obj, 0, 50);
   evas_object_color_set(obj, 128, 64, 0, 128);
}

If we wanted, we could just call evas_object_del() on the object to destroy it. In this case, no unpack is really necessary, as the box would be notified of a child being deleted and adjust its calculations accordingly.

The core of the program is the following function. It takes whatever function is first on our list of layouts and together with the last_layout, it creates an Elm_Box_Transition to use with elm_box_layout_transition(). In here, we tell it to start from whatever layout we last set, end with the one that was at the top of the list and when everything is finished, call us back so we can create another transition. Finally, move the new layout to the end of the list so we can continue running through them until the program ends.

static void
_test_box_transition_change(void *data)
{
   Transitions_Data *tdata = data;
   Elm_Box_Transition *layout_data;
   Evas_Object_Box_Layout next_layout;

   if (!data) return;
   next_layout = eina_list_data_get(tdata->transitions);
   layout_data = elm_box_transition_new(2.0, tdata->last_layout,
                                        NULL, NULL, next_layout, NULL, NULL,
                                        _test_box_transition_change, tdata);
   elm_box_layout_set(tdata->box, elm_box_layout_transition, layout_data,
                      elm_box_transition_free);
   tdata->last_layout = next_layout;

   tdata->transitions = eina_list_demote_list(tdata->transitions,
                                              tdata->transitions);
}

The main function doesn't have anything special. Creation of box, initial buttons and some callback setting. The only part worth mentioning is the initialization of our application data.

   tdata.box = bx;
   tdata.last_layout = evas_object_box_layout_horizontal;
   tdata.transitions = eina_list_append(tdata.transitions,
                                        evas_object_box_layout_vertical);
   tdata.transitions = eina_list_append(tdata.transitions,
                                        evas_object_box_layout_horizontal);
   tdata.transitions = eina_list_append(tdata.transitions,
                                        evas_object_box_layout_stack);

We have a simple static variable, set the box, the first layout we are using as last and create the list with the different functions to go through.

And in the end, we set the first layout and call the same function we went through before to start the run of transitions.

   tdata.transitions = eina_list_append(tdata.transitions,
                                        evas_object_box_layout_homogeneous_vertical);
   tdata.transitions = eina_list_append(tdata.transitions,
                                        evas_object_box_layout_homogeneous_horizontal);
   tdata.transitions = eina_list_append(tdata.transitions,
                                        evas_object_box_layout_flow_vertical);
   tdata.transitions = eina_list_append(tdata.transitions,
                                        evas_object_box_layout_flow_horizontal);
   tdata.transitions = eina_list_append(tdata.transitions,
                                        evas_object_box_layout_stack);

   elm_box_layout_set(bx, evas_object_box_layout_horizontal, NULL, NULL);
   _test_box_transition_change(&tdata);

For the full code, follow here.