[UI Sample] Email Sample Overview
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
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
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); }