Page Example

(Circle) Task Manager Sample Overview

Wearable native

The (Circle) Task Manager sample application demonstrates how you can see the recently used items and delete them. By using the scroller, box, list, and index components, you can manage multiple items and pages in Tizen.

For information on creating the sample application project in the IDE, see Creating Sample Applications.

The following figure illustrates the main screens of the (Circle) Task Manager.

Figure: (Circle) Task Manager screens

(Circle) Task Manager screens

The user can scroll through the items using the horizontal scroller. The index at the top of the screen shows where within the item list the user is currently located.

The user can delete an individual item or close all items.

Source Files

You can create and view the sample application project including the source files in the IDE.

Table: Source files
File name Description
edje/images This directory contains the image files used in the main.edc file.
inc/data.h This file contains information and definition of the variables and functions used in the C files, especially in the data.c file.
inc/taskmanager.h This file contains information and definition of the variables and functions used in the C files, especially in the main.c file.
inc/view.h This file contains information and definition of the variables and functions used in the C files, especially in the view.c file.
res/edje/main.edc This file is for the UI and contains style, image, and position of the sample application.
res/image This directory contains the image files used in the C files.
src/data.c This file contains the functions for retrieving and making data for the application.
src/main.c This file contains the functions related to the application life-cycle, callback functions, view control, and data.
src/view.c This file contains the functions for implementing the views and handling events.

Implementation

Application Layout

The view_create() function creates the view frame that consists of the window and conformant. These components are essential in creating the application UI.

void 
view_create(void)
{
   // Create the window
   s_info.win = view_create_win(PACKAGE);
   if (s_info.win == NULL) 
   {
      dlog_print(DLOG_ERROR, LOG_TAG, "failed to create a window.");

      return;
   }

   // Create the conformant
   s_info.conform = view_create_conformant_without_indicator(s_info.win);
   if (s_info.conform == NULL)
   {
      dlog_print(DLOG_ERROR, LOG_TAG, "failed to create a conformant");

      return;
   }

   // Show the window after the main view is set up
   evas_object_show(s_info.win);
}

To create additional UI features, call the view_task_manager_create() function.

From the data_get_resource_path() function, you can get the EDJ file path that is used for the application layout. After creating the layout with the given EDJ file, create a scroller for scrolling, and a box for easily managing several items.

data_get_resource_path(EDJ_FILE, edj_path, sizeof(edj_path));
view_task_manager_create(edj_path, GRP_MAIN, GRP_SCROLLER);

void 
view_task_manager_create(char *file_path, char *group_name, char *scroller_part)
{
   s_info.layout = view_create_layout(s_info.conform, file_path, group_name, _layout_back_cb, NULL);

   elm_object_content_set(s_info.conform, s_info.layout);

   s_info.scroller = view_create_horizontal_scroller(s_info.layout, scroller_part, scrolled_cb, NULL);

   s_info.box = view_create_horizontal_box(s_info.scroller, NULL);

   evas_object_show(s_info.layout);
}

The following figure illustrates the application view frame structure.

Figure: Task Manager view frame structure

Task Manager view frame structure

The size of the box is relative to the number of items packed in the box. The scroller enables you to see all items through scrolling the screen left or right.

The following figure illustrates how the frame elements are defined in the EDJ file.

Figure: Frame elements in the EDJ file

Frame elements in the EDJ file

Item Layout

The task.item.list part has a full screen size of 360 x 360 pixels.

Create a scroller to fill the area. In the view_task_manager_create() function, the GRP_SCROLLER parameter means that a scroller is put in this part, and the GRP_SCROLLER can be converted to the task.item.list part:

view_task_manager_create(edj_path, GRP_MAIN, GRP_SCROLLER);

Because the box container is added to the scroller, make each item and pack it to the box container to show the item in the task.item.list part. You can create the item with as many frames as you want.

The following figure illustrates the item frame structure.

Figure: Item frame

Item frame

To create the item and pack it to the box:

  • The view_create_1text_1image_delbutton_item() function makes the frame for the item, and through the view_set_text() function, it fills out the recent.item.name part, and using the view_set_image() function, it fills out the recent.item.image part for the icon.
  • To delete the item, register the delete_btn_clicked_cb() callback function. If the appointed clicked signal and the delete_button source are detected from the recent.item.del part, the delete_btn_clicked_cb() callback is triggered.
  • After creating the item, use the view_set_item_to_box() function to pack it to the box.
for (i = 0; i < data_get_screenshot_count(); i++) 
{
   Evas_Object *item = NULL;

   // Get appname to display the item 
   if (data_get_appname(i, appname, sizeof(appname)) != 1) 
   {
      continue;
   }

   // Get image file path to display the item
   if (data_get_screenshot(i, img_path, sizeof(img_path)) != 1) 
   {
      continue;
   }

   // Create a view that consists of 1 title, 1 icon, and a delete button
   item = view_create_1text_1image_delbutton_item(layout, edj_path, GRP_ITEM);
   // Set the 'appname' to the part named 'recent.item.name' in the EDJ file 
   view_set_text(item, "recent.item.name", appname);
   view_set_image(item, "recent.item.image", img_path);
   // Register a callback function to be called on the "clicked" event
   view_set_customized_event_callback(item, "clicked", "delete_button", delete_btn_clicked_cb, box);
   // Add an item to the box to manage it easily
   view_set_item_to_box(box, item);
   // Create a circular index to display the index of the items
   view_add_circular_index(i, data_get_screenshot_count());
}

The following figure illustrates the scroller, box, and items.

Figure: Scroller and box on the left, and items in the box on the right

Scroller and box Scroller, box, and item

Index Layout

The index is located at the top of the screen, as illustrated in the following figure.

Figure: Index

Index

To display the index location of the current item, prepare the circular index:

  • Set a full screen size for the task.item.index part.
  • The elm_object_style_set() function calculates the position based on the full screen size and determines the proper position for the circular index.
view_create_circular_index(layout, "task.item.index");

void 
view_create_circular_index(Evas_Object *parent, char *part_name)
{
   s_info.index = elm_index_add(parent);
   elm_object_style_set(s_info.index, "circle");
   evas_object_size_hint_weight_set(s_info.index, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
   evas_object_size_hint_align_set(s_info.index, EVAS_HINT_FILL, EVAS_HINT_FILL);
   elm_index_horizontal_set(s_info.index, EINA_TRUE);
   elm_index_autohide_disabled_set(s_info.index, EINA_TRUE);
   elm_object_part_content_set(parent, part_name, s_info.index);
}

After preparing the index, add an index entry whenever a new item is created:

view_add_circular_index(i, data_get_screenshot_count());

Bottom Button Layout

The bottom button is located at the bottom of the screen, and used to close all items at once.

In this sample application, however, the CLOSE ALL button is clicked, the screen is overwritten with the empty page instead of removing all items.

Figure: CLOSE ALL button

CLOSE ALL button

Create the button with the view_set_button() function. The parameters in the following example create the bottom button style, write the CLOSE ALL text on the button, register the clicked_cb() callback to be called on a click event, and insert the button in the task.del.all.btn part:

iew_set_button(layout, "task.del.all.btn", "bottom", NULL, "CLOSE ALL", NULL, NULL, clicked_cb, layout);

Empty Page Layout

The no_apps_page part is an empty page that is displayed when no items exist.

Figure: Empty page

Empty page

The page layout consists of 2 text parts and 1 image part, as illustrated in the following figure.

Figure: View frame for the empty page

View frame for the empty page

To create the no_apps_page empty page, use the GRP_NOAPPS group in the edj_path file and create the layout in the PART_NOAPPS part:

no_apps_page = view_create_layout_for_part(layout, edj_path, GRP_NOAPPS, PART_NOAPPS);

In this case, the task.title.txt and task.noapps.txt parts are not changed. When making the EDJ file, these texts are already written in each part.

part 
{ 
   name: "task.title.txt";
   type: TEXTBLOCK;
   description 
   { 
      state: "default" 0.0;
      visible: 1;
      rel1.relative: 64/360 51/360;
      rel2.relative: 296/360 90/360;
      align: 0.5 0.5;
      text 
      { 
         style: style_recent_title;
         min: 0 1;
         text: "Recent apps";
         align: 0.5 0.5;
      }
      color: 18 180 255 255;
   }
}

Deleting Items and Synchronizing the Index

When the delete button of an item is clicked, the delete_btn_clicked_cb() callback is triggered:

  1. From the elm_box_children_get() function, get the list of items in the box.
  2. Search the list to find the clicked item.
  3. If the item is found, unpack it from the box and delete it using the elm_box_unpack() and evas_object_del() functions in this order.
static void 
delete_btn_clicked_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
{
   Evas_Object *box = data;
   Eina_List *children;
   Evas_Object *child;
   int idx = -1;
   int i = 0;
   int num_item = 0;

   children = elm_box_children_get(box);
   num_item = eina_list_count(children) - 2;

   EINA_LIST_FREE(children, child) 
   {
      if (child == obj) 
      {
         idx = i;
         break;
      }
      i++;
   }

   elm_box_unpack(box, obj);
   evas_object_del(obj);

Whenever an item is added or deleted, the index must be updated accordingly. This operation is conducted by 2 functions called in the delete_btn_clicked_cb() callback:

  • The view_update_index() function deletes the index, and adds all the items in the box to the index.
  • The view_sync_index_with_item() function highlights the index according to the current item.
   view_update_index(data_get_screenshot_count());

   if (idx == num_item) 
   {
      idx = idx - 2;
   } 
   else 
   {
      idx = idx - 1;
   }
   view_sync_index_with_item(idx);
}

Customizing Event Signals

You can customize the event signal invoked by the EDJ file, as shown in the following example.

Set the program in the EDJ file to trigger a click event to the delete button named delete.item.del. This means, if the mouse,clicked event is detected from the recent.item.del part, the clicked signal is sent with the delete_button source.

part 
{ 
   name: "recent.item.del";
   type: IMAGE;
   mouse_events: 1;
   description 
   { 
      state: "default" 0.0;
      rel1 {relative: (216-63)/216 0; to: "recent.item.image";}
      rel2 {relative: 216/216 63/216; to: "recent.item.image";}
      image.normal: "b_recent_widget_del_icon.png";
      color: 184 46 46 255;
   }
   description 
   { 
      state: "pressed" 0.0;
      inherit: "default" 0.0;
      color: 184 46 46 127;
   }
   description 
   { 
      state: "closeall" 0.0;
      inherit: "default" 0.0;
      min: 40 40;
      max: 40 40;
      color: 255 255 255 0;
   }
}

programs 
{
   program 
   { 
      name: "delete.clicked";
      signal: "mouse,clicked,1";
      source: "recent.item.del";
      action: SIGNAL_EMIT "clicked" "delete_button";
   }
}

To receive this signal, register a callback function to the item to be called when the signal is detected:

view_set_customized_event_callback(item, "clicked", "delete_button", delete_btn_clicked_cb, box);

This means that if the clicked signal is detected with the delete_button source, the _delete_btn_clicked_cb() callback is triggered.

The clicked signal and the delete_button source are an appointment between C file and EDJ file, and you can customize the signal and source freely.