The (Circle) Rotary Timer sample application demonstrates how you can implement a circular digital clock with a timer function in your application.
The following figure illustrates the main views of the (Circle) Rotary Timer sample application.
Figure: (Circle) Rotary Timer main views
Click the hour, minute, and second values to set up the timer. To start the timer, click START.
The timer is stops when the number in the digital clock is reduced to 0. To set another time, click RESET.
Implementation
To implement the circular rotary timer:
- Add the required header file and callbacks.
To use the rotary function, the application must include the efl_extension.h header file. To detect rotary events, add the necessary callback functions.
eext_rotary_object_event_activated_set(ad->layout, EINA_TRUE); eext_rotary_object_event_callback_add(ad->layout, _rotary_cb, ad);
- Create the layout for the timer preview.
Use the _layout_create() function to create the main layout of the application, and add a digital clock to display the timer preview.
static Evas_Object * _layout_create(appdata_s *ad) { _D("Layout create"); Evas_Object *layout = NULL; retv_if(!ad, NULL); layout = elm_layout_add(ad->win); retv_if(!layout, NULL); main_get_resource_path(ad); // ad->timer_edj_path == app_get_resource_path() + /edje/timer.edj elm_layout_file_set(layout, ad->timer_edj_path, GRP_MAIN); evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); eext_object_event_callback_add(layout, EEXT_CALLBACK_BACK, layout_back_cb, ad); elm_object_content_set(ad->conform, layout); ad->layout = layout; _start_btn_create(ad); retv_if(!ad->start_btn, NULL); digital_create(ad); rotary_init(ad); evas_object_show(layout); return layout; }
- Initialize the application and set the timer.
Use the digital_create() function to create the digital clock and set the quantity of time for the timer.
void digital_create(appdata_s *ad) { _D("Digital create"); Evas_Object *left_col = NULL; Evas_Object *right_col = NULL; ad->hour_ly = elm_layout_add(ad->win); ret_if(!ad->hour_ly); elm_layout_file_set(ad->hour_ly, ad->timer_edj_path, "hour"); evas_object_event_callback_add(ad->hour_ly, EVAS_CALLBACK_MOUSE_DOWN, _hour_selected_cb, ad); elm_object_part_content_set(ad->layout, "hour", ad->hour_ly); elm_object_part_text_set(ad->hour_ly, "val", "00"); evas_object_show(ad->hour_ly); ad->minute_ly = elm_layout_add(ad->win); ret_if(!ad->minute_ly); elm_layout_file_set(ad->minute_ly, ad->timer_edj_path, "minute"); evas_object_event_callback_add(ad->minute_ly, EVAS_CALLBACK_MOUSE_DOWN, _minute_selected_cb, ad); elm_object_part_content_set(ad->layout, "minute", ad->minute_ly); elm_object_part_text_set(ad->minute_ly, "val", "00"); evas_object_show(ad->minute_ly); ad->second_ly = elm_layout_add(ad->win); ret_if(!ad->second_ly); elm_layout_file_set(ad->second_ly, ad->timer_edj_path, "second"); evas_object_event_callback_add(ad->second_ly, EVAS_CALLBACK_MOUSE_DOWN, _second_selected_cb, ad); elm_object_part_content_set(ad->layout, "second", ad->second_ly); elm_object_part_text_set(ad->second_ly, "val", "00"); evas_object_show(ad->second_ly); left_col = elm_image_add(ad->win); ret_if(!left_col); elm_image_file_set(left_col, ad->timer_control_dot_path, NULL); evas_object_size_hint_weight_set(left_col, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(left_col, EVAS_HINT_FILL, EVAS_HINT_FILL); elm_object_part_content_set(ad->layout, "left_colon", left_col); right_col = elm_image_add(ad->win); ret_if(!right_col); elm_image_file_set(right_col, ad->timer_control_dot_path, NULL); evas_object_size_hint_weight_set(right_col, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(right_col, EVAS_HINT_FILL, EVAS_HINT_FILL); elm_object_part_content_set(ad->layout, "right_colon", right_col); }
- Start the timer.
The _start_clicked_cb() callback starts the timer. When you click START, the application calculates the quantity of time using the _calc_setting_time() function and displays the total time. The _timer_start_cb() function is called every second to reduce the number in the digital clock.
static void _start_clicked_cb(void *data, Evas_Object *obj, void *event_info) { if (ad->timer) { _reset_clicked_cb(ad); return; } ad->setting_time = _calc_setting_time(ad); ret_if(!ad->setting_time); ad->img_num = 60; progress_count = (ad->setting_time/ad->img_num); ad->selected = NULL; // Make the digital clock unclickable elm_object_signal_emit(ad->hour_ly, "hour_deselected", "hour"); elm_object_signal_emit(ad->minute_ly, "minute_deselected", "minute"); elm_object_signal_emit(ad->second_ly, "second_deselected", "second"); elm_object_signal_emit(ad->start_btn_ly, "timer_start", "btn"); elm_object_signal_emit(ad->layout, "timer_start", "bg"); // Reduce 1 second every second ad->timer = ecore_timer_add(1.0f, _timer_start_cb, ad); ret_if(!ad->timer); ad->progress_timer = ecore_timer_add(progress_count, _progress_start_cb, ad); ret_if(!ad->progress_timer); _progress_start_cb(ad); } static Eina_Bool _timer_start_cb(void *data) { // Get the previous time pre_second_time = elm_object_part_text_get(ad->second_ly, "val"); post_second_time = atoi(pre_second_time); pre_minute_time = elm_object_part_text_get(ad->minute_ly, "val"); post_minute_time = atoi(pre_minute_time); pre_hour_time = elm_object_part_text_get(ad->hour_ly, "val"); post_hour_time = atoi(pre_hour_time); // Reduce 1 second if (post_second_time == 0) { if (post_minute_time == 0) { post_second_time = 59; post_minute_time = 59; post_hour_time = post_hour_time - 1; } else { post_second_time = 59; post_minute_time = post_minute_time - 1; } } else { post_second_time = post_second_time - 1; } // Display the new time elm_object_part_text_set(ad->hour_ly, "val", hour_val); elm_object_part_text_set(ad->minute_ly, "val", minute_val); elm_object_part_text_set(ad->second_ly, "val", second_val); ad->setting_time--; free(hour_val); free(minute_val); free(second_val); return ECORE_CALLBACK_RENEW; }
- Reset the timer.
To set another time when the user clicks RESET, call the _reset_clicked_cb() callback function.
static void _reset_clicked_cb(appdata_s *ad) { ad->setting_time = 0; ecore_timer_del(ad->timer); ad->timer = NULL; ecore_timer_del(ad->progress_timer); ad->progress_timer = NULL; elm_object_part_text_set(ad->hour_ly, "val", "00"); elm_object_part_text_set(ad->minute_ly, "val", "00"); elm_object_part_text_set(ad->second_ly, "val", "00"); elm_object_signal_emit(ad->start_btn_ly, "timer_end", "btn"); elm_object_signal_emit(ad->layout, "timer_end", "bg"); elm_object_signal_emit(ad->layout, "timer_end", "progress"); }