Rotary Timer Sample Overview

Wearable native

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

(Circle) Rotary Timer main views (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:

  1. 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);
  2. 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;
    }
  3. 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);
    }
  4. 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;
    }
  5. 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");
    }