
The (Circle) Settings sample application demonstrates how to implement a circular view with the elementary UI components and EFL Extension circular UI components.
The sample uses UI components, such as elm_conformant and elm_naviframe for view management, elm_layout for UI component management inside the view, and elm_genlist for the content inside the main view. elm_genlist has three items: volume, brightness and information. When the item is clicked, its content is shown. To display a circular genlist component, the genlist component uses a circular genlist component supported by the EFL Extension.
The following figure illustrates the main view of the (Circle) Settings sample application, its wireframe structure, and component tree.
Figure: (Circle) Settings main view
_Settings_UI/images/circle_setting_sd.png)
_Settings_UI/images/circle_setting_tree.png)
Implementation
Main View
The create_base_gui() function is responsible for creating the application layout. It starts by creating a window, then adds elm_conformant to it to add surface for the circular component visual effect renderer. The conformant contains a layout for elm_naviframe which is added to act as a view manager of the window.
static void
create_base_gui(appdata_s *ad)
{
Evas_Object *conform = NULL;
// Window
ad->win = elm_win_util_standard_add(PACKAGE, PACKAGE);
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
conform = elm_conformant_add(ad->win);
evas_object_size_hint_weight_set(conform, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
elm_win_resize_object_add(ad->win, conform);
evas_object_show(conform);
// Naviframe
ad->naviframe = elm_naviframe_add(conform);
elm_object_content_set(conform, ad->naviframe);
// Eext Circle Surface
ad->circle_surface = eext_circle_surface_naviframe_add(ad->naviframe);
// Main View
create_list_view(ad);
eext_object_event_callback_add(ad->naviframe, EEXT_CALLBACK_BACK, eext_naviframe_back_cb, NULL);
eext_object_event_callback_add(ad->naviframe, EEXT_CALLBACK_MORE, eext_naviframe_more_cb, NULL);
// Show the window after the base GUI is set up
evas_object_show(ad->win);
}
The main view is created using the create_list_view() function and it is added to the naviframe. In this function, the circular genlist is created for the circular UI which requires the genlist object to initialize itself. After that, three setting items are generated and appended to the circular genlist.
static void
create_list_view(appdata_s *ad)
{
Evas_Object *genlist = NULL;
Evas_Object *naviframe = ad->naviframe;
Elm_Object_Item *nf_it = NULL;
Elm_Genlist_Item_Class *itc = elm_genlist_item_class_new();
Elm_Genlist_Item_Class *titc = elm_genlist_item_class_new();
Elm_Genlist_Item_Class *pitc = elm_genlist_item_class_new();
item_data *id = NULL;
int index = 0;
// Genlist
genlist = elm_genlist_add(naviframe);
elm_genlist_mode_set(genlist, ELM_LIST_COMPRESS);
evas_object_smart_callback_add(genlist, "selected", NULL, NULL);
ad->circle_genlist = eext_circle_object_genlist_add(genlist, ad->circle_surface);
eext_circle_object_genlist_scroller_policy_set(ad->circle_genlist, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_AUTO);
eext_rotary_object_event_activated_set(ad->circle_genlist, EINA_TRUE);
// Genlist item style
itc->item_style = "default";
itc->func.text_get = _gl_main_text_get;
itc->func.del = _gl_del;
// Genlist title item style
titc->item_style = "title";
titc->func.text_get = _gl_title_text_get;
titc->func.del = _gl_del;
// Genlist padding item style
pitc->item_style = "padding";
// Title item here
elm_genlist_item_append(genlist, titc, NULL, NULL, ELM_GENLIST_ITEM_NONE, NULL, ad);
// Main menu items here
id = calloc(sizeof(item_data), 1);
id->index = index++;
id->item = elm_genlist_item_append(genlist, itc, id, NULL, ELM_GENLIST_ITEM_NONE, _setting_volume_cb, ad);
id = calloc(sizeof(item_data), 1);
id->index = index++;
id->item = elm_genlist_item_append(genlist, itc, id, NULL, ELM_GENLIST_ITEM_NONE, _setting_brightness_cb, ad);
id = calloc(sizeof(item_data), 1);
id->index = index++;
id->item = elm_genlist_item_append(genlist, itc, id, NULL, ELM_GENLIST_ITEM_NONE, _setting_information_cb, ad);
// Padding item here
elm_genlist_item_append(genlist, pitc, NULL, NULL, ELM_GENLIST_ITEM_NONE, NULL, ad);
nf_it = elm_naviframe_item_push(naviframe, NULL, NULL, NULL, genlist, "empty");
elm_naviframe_item_pop_cb_set(nf_it, _naviframe_pop_cb, ad->win);
}
Volume View
When the volume item is clicked, the volume view is shown in the main view. The following figure illustrates the volume view and its wireframe structure.
Figure: (Circle) Settings volume view
_Settings_UI/images/circle_setting_volume_view.png)
The _setting_volume_cb() callback function is called when the first item whose name is volume is clicked. In this function, a circular slider object is created by the eext_circle_object_slider_add() function. It needs the circular surface to render the circular slider on the surface. The eext_rotary_object_event_activated_set() function is called to receive the rotary event. After that, the _value_changed_cb() callback function is added to the circular slider to change the text as the circular slider value is changed.
static void
_setting_volume_cb(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
{
char edj_path[PATH_MAX] = {0,};
appdata_s *ad = data;
Evas_Object *naviframe = ad->naviframe;
Evas_Object *layout = NULL;
Evas_Object *slider = NULL;
Elm_Object_Item *nf_it = NULL;
app_get_resource(EDJ_FILE, edj_path, (int)PATH_MAX);
layout = elm_layout_add(naviframe);
elm_layout_file_set(layout, edj_path, "slider_layout");
elm_object_part_text_set(layout, "elm.text.slider", "3.0");
evas_object_show(layout);
slider = eext_circle_object_slider_add(layout, ad->circle_surface);
eext_circle_object_value_min_max_set(slider, 0.0, 15.0);
eext_circle_object_value_set(slider, 3.0);
eext_rotary_object_event_activated_set(slider, EINA_TRUE);
eext_circle_object_slider_step_set(slider, 0.5);
evas_object_smart_callback_add(slider, "value,changed", _volume_changed_cb, layout);
nf_it = elm_naviframe_item_push(naviframe, _("Slider"), NULL, NULL, layout, "empty");
elm_naviframe_item_pop_cb_set(nf_it, _setting_finished_cb, ad);
}
The _volume_changed_cb() callback function is called when the volume value is changed. In this function, the layout text is changed using the eext_circle_object_value_get() function which gets the current value of the circular slider.
static void
_volume_changed_cb(void *data, Evas_Object *obj, void *event_info)
{
char buf[PATH_MAX];
Evas_Object *layout = data;
snprintf(buf, sizeof(buf), "%.1lf", eext_circle_object_value_get(obj));
printf("Slider value = %s\n", buf);
elm_object_part_text_set(layout, "elm.text.slider", buf);
}
Brightness View
When the brightness item is clicked, the brightness view is shown in the main view. The following figure illustrates the brightness view and its wireframe structure.
Figure: (Circle) Settings brightness view
_Settings_UI/images/circle_setting_brightness_view.png)
The _setting_brightness_cb() callback function is called when the second item whose name is brightness is clicked. In this function, a circular slider object is created by the eext_circle_object_slider_add() function and 10 rectangles are created to display the circular slider value visually. Also, the _brightness_changed_cb() callback function is registered to change the value as the circular slider has changed.
static void
_setting_brightness_cb(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
{
char edj_path[PATH_MAX] = {0,};
appdata_s *ad = data;
Evas_Object *naviframe = ad->naviframe;
Evas_Object *layout = NULL;
Evas_Object *slider = NULL;
Evas_Object *box = NULL;
Evas_Object *rect[10] = {NULL,};
Elm_Object_Item *nf_it = NULL;
int i;
app_get_resource(EDJ_FILE, edj_path, (int)PATH_MAX);
layout = elm_layout_add(naviframe);
elm_layout_file_set(layout, edj_path, "slider_layout");
evas_object_show(layout);
box = elm_box_add(layout);
elm_box_horizontal_set(box, EINA_TRUE);
elm_box_padding_set(box, 3, 0);
evas_object_show(box);
elm_object_part_content_set(layout, "elm.swallow.content", box);
for (i = 0; i < 10; ++i)
{
rect[i] = evas_object_rectangle_add(evas_object_evas_get(layout));
evas_object_color_set(rect[i], 0, 255, 0, 75);
evas_object_size_hint_min_set(rect[i], 20, 20);
evas_object_show(rect[i]);
elm_box_pack_end(box, rect[i]);
}
for (i = 0; i < 10; ++i)
ad->rect[i] = rect[i];
slider = eext_circle_object_slider_add(layout, ad->circle_surface);
eext_circle_object_value_min_max_set(slider, 0.0, 10.0);
eext_circle_object_value_set(slider, 0.0);
eext_rotary_object_event_activated_set(slider, EINA_TRUE);
eext_circle_object_slider_step_set(slider, 1.0);
evas_object_smart_callback_add(slider, "value,changed", _brightness_changed_cb, ad);
nf_it = elm_naviframe_item_push(naviframe, _("Slider"), NULL, NULL, layout, "empty");
elm_naviframe_item_pop_cb_set(nf_it, _setting_finished_cb, ad);
}
The _brightness_changed_cb() callback is called when the brightness value is changed. Here, the rectangles are redrawn using the eext_circle_object_value_get() function value.
static void
_brightness_changed_cb(void *data, Evas_Object *obj, void *event_info)
{
appdata_s *ad = data;
int i, value;
value = eext_circle_object_value_get(obj);
for (i = 0; i < 10; ++i)
{
if (i < value)
evas_object_color_set(ad->rect[i], 0, 255, 0, 150);
else
evas_object_color_set(ad->rect[i], 0, 255, 0, 75);
}
}
Information View
When the information item is clicked, the information view is shown in the main view. The following figure illustrates the information view and its wireframe structure.
Figure: (Circle) Settings information view
_Settings_UI/images/circle_setting_information_view.png)
The _setting_information_cb() function creates a layout whose name is slider_layout. The layout has two swallow parts for a scroller and a button. The scroller with the label set to elm.swallow.content and the button is set to elm.swallow.button with the bottom style.
static void
_setting_information_cb(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
{
char edj_path[PATH_MAX] = {0,};
appdata_s *ad = data;
Evas_Object *naviframe = ad->naviframe;
Evas_Object *layout = NULL;
Evas_Object *label = NULL;
Evas_Object *button = NULL;
Evas_Object *scroller = NULL;
Evas_Object *circle_scroller = NULL;
Elm_Object_Item *nf_it = NULL;
app_get_resource(EDJ_FILE, edj_path, (int)PATH_MAX);
layout = elm_layout_add(naviframe);
elm_layout_file_set(layout, edj_path, "info_layout");
evas_object_show(layout);
scroller = elm_scroller_add(layout);
evas_object_show(scroller);
elm_object_part_content_set(layout, "elm.swallow.content", scroller);
circle_scroller = eext_circle_object_scroller_add(scroller, ad->circle_surface);
eext_circle_object_scroller_policy_set(circle_scroller, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_AUTO);
eext_rotary_object_event_activated_set(circle_scroller, EINA_TRUE);
label = elm_label_add(scroller);
elm_label_line_wrap_set(label, ELM_WRAP_MIXED);
elm_object_text_set(label, "This is setting application, "
"By using the movement of the rotary, "
"you can change the value of volume and brightness.");
evas_object_show(label);
elm_object_content_set(scroller, label);
button = elm_button_add(layout);
elm_object_style_set(button, "bottom/queue");
elm_object_text_set(button, "OK");
elm_object_part_content_set(layout, "elm.swallow.button", button);
evas_object_smart_callback_add(button, "clicked", _button_clicked_cb, ad);
evas_object_show(button);
nf_it = elm_naviframe_item_push(naviframe, _("Slider"), NULL, NULL, layout, "empty");
}