Page Example

Email UI Sample Overview

Mobile native

The [UI Sample] Email sample application demonstrates how to implement a complex view by a recursive composition of standard EFL UI components and containers in a UI component hierarchy.

The sample uses UI components, such as elm_conformant, elm_naviframe and elm_layout for the view management, containers, such as elm_list, elm_genlist, and elm_panel for the UI component management inside the view, and UI components, such as elm_button and elm_image for the content inside view.

Main View

The following figure illustrates the main view of the [UI Sample] Email sample application, its wireframe structure, and the UI component tree.

Figure: [UI Sample] Email main view

[UI Sample] Email main view

[UI Sample] Email main view

[UI Sample] Email main view

The create_base_gui() function creates the window which consists of an indicator (elm_conformant), view manager (elm_naviframe), and the content created by using the create_main_view() function. The drawer and compose button are inserted in the naviframe.

static void
create_base_gui(appdata_s *ad)
{
   Evas_Object *btn1, *btn2, *bg;
   Elm_Object_Item *nf_it;

   // Window
   ad->win = elm_win_util_standard_add(PACKAGE, PACKAGE);
   elm_win_conformant_set(ad->win, EINA_TRUE);
   elm_win_autodel_set(ad->win, EINA_TRUE);

   if (elm_win_wm_rotation_supported_get(ad->win)) 
   {
      int rots[4] = {0, 90, 180, 270};
      elm_win_wm_rotation_available_rotations_set(ad->win, (const int *)(&rots), 4);
   }
   evas_object_smart_callback_add(ad->win, "delete,request", win_delete_request_cb, NULL);

   // Conformant
   ad->conform =  elm_conformant_add(ad->win);
   elm_win_indicator_mode_set(ad->win, ELM_WIN_INDICATOR_SHOW);
   elm_win_indicator_opacity_set(ad->win, ELM_WIN_INDICATOR_OPAQUE);
   elm_win_resize_object_add(ad->win, ad->conform);
   evas_object_show(ad->conform);

   // Indicator BG
   bg = elm_bg_add(ad>conform);
   elm_object_style_set(bg, "indicator/headerbg");
   elm_object_part_content_set(ad>conform, "elm.swallow.indicator_bg", bg);
   evas_object_show(bg);

   // Main view
   ad->base_ly = create_main_view(ad);
   elm_object_content_set(ad>conform, ad>base_ly);

   // Naviframe
   ad->nf = elm_naviframe_add(ad->base_ly);
   eext_object_event_callback_add(ad>nf, EEXT_CALLBACK_BACK, eext_naviframe_back_cb, ad);
   elm_object_part_content_set(ad->base_ly, "elm.swallow.content", ad->nf);
   evas_object_show(ad->nf);

   // Genlist
   ad>genlist = create_genlist(ad>nf);

   nf_it = elm_naviframe_item_push(ad->nf, "In Box", NULL, NULL, ad->genlist, NULL);
   elm_naviframe_item_pop_cb_set(nf_it, nf_it_pop_cb, ad);
   elm_object_item_part_text_set(nf_it, "subtitle", user_email);

   // Left panel toggle button
   btn1 = create_button(ad->nf, "naviframe/drawers", NULL);
   evas_object_smart_callback_add(btn1, "clicked", _left_panel_button_clicked_cb, ad);
   elm_object_item_part_content_set(nf_it, "title_left_btn", btn1);

   // Right compose button
   btn2 = create_button(ad->nf, NULL, "<font_size=20>New</font_size>");
   evas_object_smart_callback_add(btn2, "clicked", _composer_button_clicked_cb, ad);
   elm_object_item_part_content_set(nf_it, "title_right_btn", btn2);

   // Show the window after the base GUI is set up
   evas_object_show(ad->win);
}

The create_main_view() function creates the content of the view. First, the base layout is created. The drawer (panel) list and genlist are also created. The drawer and genlist are inserted in the layout. The drawer contains a list.

static Evas_Object *
create_main_view(appdata_s *ad)
{
   Evas_Object *layout;

   // Drawer layout
   layout = create_base_layout(ad->conform);

   // Panel
   ad->panel = create_panel(layout);
   elm_object_part_content_set(layout, "elm.swallow.left", ad->panel);

   // Panel list
   ad->panel_list = create_panel_list(ad->panel);
   evas_object_size_hint_weight_set(ad->panel_list, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
   evas_object_size_hint_align_set(ad->panel_list, EVAS_HINT_FILL, EVAS_HINT_FILL);
   evas_object_smart_callback_add(ad->panel_list, "selected", _list_clicked_cb, ad);
   elm_object_content_set(ad->panel, ad->panel_list);

   return layout;
}
The create_genlist() function creates a genlist. The genlist has 2 item classes, group item and item.
static Evas_Object *
create_genlist(Evas_Object *parent)
{
   // Create item class
   Elm_Genlist_Item_Class *gitc = elm_genlist_item_class_new();
   Elm_Genlist_Item_Class *itc = elm_genlist_item_class_new();

   gitc->item_style = "groupindex";
   gitc->func.text_get = gl_text_get_cb;
   gitc->func.content_get = gl_content_get_cb;
   gitc->func.del = gl_del_cb;

   itc->item_style = "2line.top.3";
   itc->func.text_get = gl_text_get_cb;
   itc->func.content_get = gl_content_get_cb;
   itc->func.del = gl_del_cb;

   genlist = elm_genlist_add(parent);

   int group_count = 0;
   for (index = 0; index < n_items; index++) 
   {
      item_data_s *id = calloc(sizeof(item_data_s), 1);
      id->index = index;
      if (index % 10 == 0) 
      {
         group_count++;
         id->index = group_count;
         git = elm_genlist_item_append(genlist, // Genlist object
                     gitc, // Item class
                     id, // Item class user data
                     NULL,
                     ELM_GENLIST_ITEM_GROUP, // Item type
                     gl_selected_cb, // Select smart callback
                     id); // Smart callback user data
         id->item = git;
      }
      else 
      {
         it = elm_genlist_item_append(genlist, // Genlist object
                     itc, // Item class
                     id, // Item class user data
                     git, // Parent item
                     ELM_GENLIST_ITEM_NONE, // Item type
                     gl_selected_cb, // Select smart callback
                     id); // Smart callback user data
         id->item = it;
      }
   }
   elm_genlist_item_class_free(gitc);
   elm_genlist_item_class_free(itc);
   evas_object_show(genlist);

   return genlist;
}

Compose View

The following figure illustrates the main screen of the Compose view, its wireframe structure, and the UI component tree.

Figure: Compose view

Email compose view

Email compose UI component tree

evas_object_smart_callback_add(btn, "clicked", _composer_button_clicked_cb, ad);

In this sample, a smart callback for clicking the compose button is added by default.

The smart callback is called when the compose button is clicked. In this callback, the compose view is created. It consists of a scroller containing a box. The box contains 4 entries. The vertical weight of the box is 0.0, which means that the box resizes to the minimum size.

static void
_composer_button_clicked_cb(void *data, Evas_Object * obj, void *event_info)
{
   appdata_s *ad = data;
   cdata_s *cd = calloc(1, sizeof(cdata_s));
   cd->ad = ad;
   Evas_Object *btn, *scroller, *main_box, *myemail, *to, *subject, *content;
   Elm_Object_Item *nf_it;

   scroller = create_scroller(ad->nf);

   // Append box
   main_box = create_box(scroller);
   evas_object_size_hint_weight_set(main_box, EVAS_HINT_EXPAND, 0.0);
   evas_object_size_hint_align_set(main_box, EVAS_HINT_FILL, EVAS_HINT_FILL);
   elm_box_padding_set(main_box, 0, 30);
   elm_object_content_set(scroller, main_box);

   // Use email
   myemail = create_entry(main_box, user_email, NULL);
   elm_entry_editable_set(myemail, EINA_FALSE);
   elm_entry_single_line_set(myemail, EINA_TRUE);
   evas_object_size_hint_weight_set(myemail, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
   evas_object_size_hint_align_set(myemail, EVAS_HINT_FILL, EVAS_HINT_FILL);
   elm_box_pack_end(main_box, myemail);

   // To
   to = create_entry(main_box, NULL, "To");
   evas_object_size_hint_weight_set(to, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
   evas_object_size_hint_align_set(to, EVAS_HINT_FILL, EVAS_HINT_FILL);
   elm_box_pack_end(main_box, to);
   cd->to = to;

   // Subject
   subject = create_entry(main_box, NULL, "Subject");
   evas_object_size_hint_weight_set(subject, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
   evas_object_size_hint_align_set(subject, EVAS_HINT_FILL, EVAS_HINT_FILL);
   elm_box_pack_end(main_box, subject);
   cd->subject = subject;

   // Content
   content = create_entry(main_box, NULL, "Compose email");
   evas_object_size_hint_weight_set(content, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
   evas_object_size_hint_align_set(content, EVAS_HINT_FILL, EVAS_HINT_FILL);
   elm_box_pack_end(main_box, content);
   cd->content = content;

   nf_it = elm_naviframe_item_push(ad->nf, "Compose", NULL, NULL, scroller, NULL);

   // Back button
   btn = create_button(ad->nf, "naviframe/title_cancel", NULL);
   evas_object_smart_callback_add(btn, "clicked", _back_button_clicked_cb, cd);
   elm_object_item_part_content_set(nf_it, "title_left_btn", btn);

   // Send button
   btn = create_button(ad->nf, "naviframe/title_done", NULL);
   evas_object_smart_callback_add(btn, "clicked", _send_button_clicked_cb, cd);
   elm_object_item_part_content_set(nf_it, "title_right_btn", btn);
}