Simple home Sample Overview

Mobile native

The Simple Homescreen sample application demonstrates how to implement a Homescreen-like application using the Application Manager API.

The following figure illustrates the application views.

Figure: Simple Homescreen screens

Main view App info displayed Icon rearrangement

The application displays a list of all applications that are installed on the device and available for the end user (the nodisplay flag is set to false in the applications' tizen-manifest.xml files).

The main window contains an application grid, horizontally scrollable, where appropriate icons are displayed. The application scans all installed packages looking for displayable ones (those that can be displayed to the end user).

You can:

  • Tap on application icon to see a pop-up window with the following information:
    • Simplified application name (typically displayed below the icon on the home screen)
    • Full path to the application icon resource image
    • Package name of the application
  • Drag and drop the application icon to rearrange the icon position within the Simple Homescreen application

Implementation

The _on_create_cb() callback function initializes the application model and user interface:

static bool _on_create_cb(void *user_data)
{
   app_data *ad = user_data;
   RETVM_IF(!ad, false, "ad is NULL");

   elm_app_base_scale_set(1.8);

   ad->win = win_create();
   RETVM_IF(!ad->win, false, "win is NULL");

   Evas_Object *content = main_view_add(ad, ad->win->conform);
   RETVM_IF(!content, false, "content is NULL");

   win_set_content(ad->win, content);

   return true;
}

The following figure illustrates the structure of application base view.

Figure: Simple Homescreen base view

Simple Homescreen base view

The win_create() function creates a window which consists of an indicator (elm_conformant) and a background.

window_obj *win_create()
{
   window_obj *obj = calloc(1, sizeof(window_obj));
   if (!obj)
   {
      return NULL;
   }

   obj->win = elm_win_util_standard_add(APP_NAME, APP_NAME);
   elm_win_autodel_set(obj->win, EINA_TRUE);
   elm_win_conformant_set(obj->win, EINA_TRUE);
   evas_object_size_hint_weight_set(obj->win, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
   elm_win_indicator_mode_set(obj->win, ELM_WIN_INDICATOR_SHOW);
   evas_object_show(obj->win);

   obj->conform = elm_conformant_add(obj->win);
   evas_object_size_hint_weight_set(obj->conform, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
   elm_win_resize_object_add(obj->win, obj->conform);
   evas_object_show(obj->conform);

   obj->bg = elm_bg_add(obj->conform);
   evas_object_size_hint_weight_set(obj->bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
   evas_object_show(obj->bg);

   elm_object_part_content_set(obj->conform, "elm.swallow.bg", obj->bg);

   return obj;
}

The main_view_add() function creates the main view gengrid, gets all applications from the model, and pushes the application icons into the gengrid. This function also registers a callback for the back key click.

Evas_Object *main_view_add(app_data *app, Evas_Object *parent)
{
   RETVM_IF(!app || !parent, NULL, "Passed NULL input data");

   main_view_data *data = calloc(1, sizeof(main_view_data));
   data->win = app->win;
   app->main_view_data = data;

   data->gengrid = gengrid_create(data->win->win);

   data->app_list = app_manager_all_apps_get();
   Eina_List *it = NULL;
   app_info_h *app_info = NULL;
   EINA_LIST_FOREACH(data->app_list, it, app_info)
   {
      gengrid_item_append(data->gengrid, app_info);
   }

   eext_object_event_callback_add(data->gengrid, EEXT_CALLBACK_BACK, _main_view_hardware_buttons_cb, data);

   return data->gengrid;
}

The app_manager_all_apps_get() function iterates over all the installed applications using the app_manager_foreach_app_info() function. The _app_manager_app_info_cb() clones each application context handle and pushes them to the list.

bool _app_manager_app_info_cb(app_info_h app_info, void *user_data)
{
   bool nodisplay;
   _app_is_success(app_info_is_nodisplay(app_info, &nodisplay));
   if (!nodisplay)
   {
   Eina_List **app_list = user_data;
   app_info_h *clone = malloc(sizeof(app_info_h));
   _app_is_success(app_info_clone(clone, app_info));
   *app_list = eina_list_append(*app_list, clone);
   }

   return true;
}

Eina_List *app_manager_all_apps_get()
{
   Eina_List *app_list = NULL;
   app_manager_foreach_app_info(_app_manager_app_info_cb, &app_list);

   return app_list;
}

The gengrid_create() function creates a gengrid using the elm_gengrid_add() function.

The gengrid item size is set to predefined values with the elm_gengrid_item_size_set() function. In order to allow the item position rearrangement by drag and drop, the reorder mode is set using the elm_gengrid_reorder_mode_set() function.

Evas_Object *gengrid_create(Evas_Object *parent)
{
   RETVM_IF(!parent, NULL, "Passed NULL parent data");

   if (!itc)
   {
       _gengrid_item_class_initialize();
   }

   Evas_Object *gengrid = elm_gengrid_add(parent);
   elm_gengrid_item_size_set(gengrid, ELM_SCALE_SIZE(GENGRID_ITEM_WIDTH), ELM_SCALE_SIZE(GENGRID_ITEM_HEIGHT));
   elm_gengrid_reorder_mode_set(gengrid, EINA_TRUE);
   elm_gengrid_horizontal_set(gengrid, EINA_TRUE);

   evas_object_size_hint_weight_set(gengrid, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
   evas_object_size_hint_align_set(gengrid, EVAS_HINT_FILL, EVAS_HINT_FILL);

   return gengrid;
}

Each item is appended using the elm_gengrid_item_append() function. The function takes 5 parameters:

  • Gengrid object to which an item is appended
  • Item class
  • Item data
  • Function to be called when the item is selected
  • Additional data to be passed to the function
Elm_Object_Item *gengrid_item_append(Evas_Object *gengrid, app_info_h *app_info)
{
   RETVM_IF(!gengrid || !app_info, NULL, "Passed NULL input data");

   if (!itc)
   {
      _gengrid_item_class_initialize();
   }

   Elm_Object_Item *item = elm_gengrid_item_append(gengrid, itc, app_info, _gengrid_item_selected, app_info);

   return item;
}

The gengrid item class defines an item style as well as callbacks to be used at retrieving item attributes (text, content, or state). The class is used when an item is added to a gengrid. The gengrid item class used in this application is initialized in the _gengrid_item_class_initialize() function. The item style is set to default. Items in the gengrid consist only of an icon, so the text_get callback and state_get callbacks are set to NULL as they are not used.

The _grid_content_get() function is the content_get callback invoked when an item is added, returning an icon of the given application. For the default gengrid item theme used in the application, each item has 2 content parts: "elm.swallow.icon" and "elm.swallow.end". Only "elm.swallow.icon" is used here, but the content_get callback is used to retrieve content for both parts. For that reason, a part name check is needed before the icon image is created and returned as the icon content.

Evas_Object *_grid_content_get(void *data, Evas_Object *obj, const char *part)
{
   if (!strcmp(part, "elm.swallow.icon"))
   {
      Evas_Object *image = elm_image_add(obj);
      app_info_h *app_info = (app_info_h*)data;
      char *icon;
      app_info_get_icon(*app_info, &icon);
      if (!elm_image_file_set(image, icon, NULL))
      {
         evas_object_del(image);
         Evas_Object *bg = elm_bg_add(obj);
         elm_bg_color_set(bg, 255, 255, 0);

         return bg;
      }

      return image;
   }

   return NULL;
}

void _gengrid_item_class_initialize()
{
   itc = elm_gengrid_item_class_new();
   itc->item_style = "default";
   itc->func.text_get = NULL;
   itc->func.content_get = _grid_content_get;
   itc->func.state_get = NULL;
   itc->func.del = NULL;
}

When an item is selected, a pop-up is created to display the selected application's data.

void _gengrid_item_selected(void *data, Evas_Object *obj, void *event_info)
{
   popup_create(obj, (app_info_h*)data);
}

The popup_create() function takes app_info_h as a parameter, which is then used to acquire the application label, icon, and package name. The label is set as the pop-up title (the "title,text" part) whereas the remaining data is set as its content (the "default" part). The elm_popup_timeout_set() function sets a timeout to hide the pop-up automatically after POPUP_TIMEOUT (5) seconds.

A callback on the "block,clicked" event is set for the pop-up so that it is deleted after the user clicks outside its area.

void popup_create(Evas_Object *parent, app_info_h *app_info)
{
   RETM_IF(!parent || !app_info, "Passed NULL input data");

   Evas_Object *popup = elm_popup_add(parent);

   char *label;
   char *icon;
   char *package;
   app_label_get(app_info, &label);
   app_icon_get(app_info, &icon);
   app_package_get(app_info, &package);

   elm_object_part_text_set(popup, "title,text", label);
   char info[BUF_SIZE];
   snprintf(info, BUF_SIZE, "Icon path:<br>%s<br><br>Package:<br>%s", icon, package);

   elm_object_part_text_set(popup, "default", info);

   free(label);
   free(icon);
   free(package);

   evas_object_smart_callback_add(popup, "block,clicked", _block_clicked, NULL);
   elm_popup_timeout_set(popup, 5.0);

   evas_object_show(popup);
}

static void _block_clicked(void *data, Evas_Object *obj, void *event_info)
{
   evas_object_del(obj);
}