Tizen(Headed) Native API  6.5
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 full code of the example is here and we will follow here with a rundown of it.

#include <Elementary.h>
typedef struct
{
   Evas_Object *mid;
   Evas_Object *icon_still;
   struct
     {
        Evas_Object *up;
        Evas_Object *down;
        Evas_Object *left;
        Evas_Object *right;
     } cursors;
} App_Data;

We have several buttons to set different times for the autorepeat timeouts of the buttons that use it and a few more that we keep track of in our data struct. The mid button doesn't do much, just moves around according to what other buttons the user presses. Then four more buttons to move the central one, and we're also keeping track of the icon set in the middle button, since when this one moves, we change the icon, and when movement is finished (by releasing one of the four arrow buttons), we set back the normal icon.

static void
_btn_cursors_release_cb(void *data, Evas_Object *btn EINA_UNUSED,
                        void *ev EINA_UNUSED)
{
   App_Data *app = data;
   elm_object_part_content_set(app->mid, "icon", app->icon_still);
   app->icon_still = NULL;
}

Keeping any of those four buttons pressed will trigger their autorepeat callback, where we move the button doing some size hint magic. To understand how that works better, refer to the Elm_Box documentation. Also, the first time the function is called, we change the icon in the middle button, using elm_object_content_unset() first to keep the reference to the previous one, so we don't need to recreate it when we are done moving it.

static void
_btn_cursors_move_cb(void *data, Evas_Object *btn, void *ev EINA_UNUSED)
{
   App_Data *app = data;
   double ax, ay;

   if (!app->icon_still)
     {
        Evas_Object *icon;
        app->icon_still = elm_object_content_unset(app->mid);
        evas_object_hide(app->icon_still);
        icon = elm_icon_add(app->mid);
        elm_icon_standard_set(icon, "chat");
        elm_object_part_content_set(app->mid, "icon", icon);
     }

   evas_object_size_hint_align_get(app->mid, &ax, &ay);
   if (btn == app->cursors.up)
     {
        ay -= 0.05;
        if (ay < 0.0)
          ay = 0.0;
     }
   else if (btn == app->cursors.down)
     {
        ay += 0.05;
        if (ay > 1.0)
          ay = 1.0;
     }
   else if (btn == app->cursors.left)
     {
        ax -= 0.05;
        if (ax < 0.0)
          ax = 0.0;
     }
   else if (btn == app->cursors.right)
     {
        ax += 0.05;
        if (ax > 1.0)
          ax = 1.0;
     }
   evas_object_size_hint_align_set(app->mid, ax, ay);
}

One more callback for the option buttons, that just sets the timeouts for the different autorepeat options.

static void
_btn_options_cb(void *data, Evas_Object *btn, void *ev EINA_UNUSED)
{
   char *ptr;
   double t;
   App_Data *app = data;
   const char *lbl = elm_object_text_get(btn);

   ptr = strchr(lbl, ':');
   ptr += 2;
   t = strtod(ptr, NULL);

   if (!strncmp(lbl, "Initial", 7))
     {
        elm_button_autorepeat_initial_timeout_set(app->cursors.up, t);
        elm_button_autorepeat_initial_timeout_set(app->cursors.down, t);
        elm_button_autorepeat_initial_timeout_set(app->cursors.left, t);
        elm_button_autorepeat_initial_timeout_set(app->cursors.right, t);
     }
   else if (!strncmp(lbl, "Gap", 3))
     {
        elm_button_autorepeat_gap_timeout_set(app->cursors.up, t);
        elm_button_autorepeat_gap_timeout_set(app->cursors.down, t);
        elm_button_autorepeat_gap_timeout_set(app->cursors.left, t);
        elm_button_autorepeat_gap_timeout_set(app->cursors.right, t);
     }
}

And the main function, which does some setting up of the buttons in boxes to make things work. Here we'll go through some snippets only.

For the option buttons, it's just the button with its label and callback.

   btn = elm_button_add(win);
   elm_object_text_set(btn, "Initial: 0.0");
   elm_box_pack_end(box2, btn);
   evas_object_show(btn);
   evas_object_smart_callback_add(btn, "clicked", _btn_options_cb, &data);

For the ones that move the central button, we have no labels. There are icons instead, and the autorepeat option is toggled.

   btn = elm_button_add(win);
   elm_button_autorepeat_set(btn, EINA_TRUE);
   elm_button_autorepeat_initial_timeout_set(btn, 1.0);
   elm_button_autorepeat_gap_timeout_set(btn, 0.5);
   evas_object_size_hint_weight_set(btn, EVAS_HINT_EXPAND, 0.0);
   evas_object_size_hint_align_set(btn, EVAS_HINT_FILL, 0.0);
   elm_box_pack_end(box, btn);
   evas_object_show(btn);
   evas_object_smart_callback_add(btn, "repeated", _btn_cursors_move_cb, &data);
   evas_object_smart_callback_add(btn, "unpressed", _btn_cursors_release_cb,
                                  &data);

   icon = elm_icon_add(win);
   elm_icon_standard_set(icon, "arrow_up");
   elm_object_part_content_set(btn, "icon", icon);

   data.cursors.up = btn;

And just to show the mid button, which doesn't have anything special.

   btn = elm_button_add(win);
   evas_object_size_hint_weight_set(btn, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
   elm_box_pack_end(box2, btn);
   evas_object_show(btn);

   icon = elm_icon_add(win);
   elm_icon_standard_set(icon, "close");
   elm_object_part_content_set(btn, "icon", icon);

   data.mid = btn;

And we are done.