ami pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=0bcb0302fb647b43cef4e633cf0c0b16e5521e04

commit 0bcb0302fb647b43cef4e633cf0c0b16e5521e04
Author: Amitesh Singh <[email protected]>
Date:   Thu Nov 3 12:00:17 2016 +0530

    efl_ui_clock: Merge datetime/dayselector/clock widgets into efl_ui_clock.
    
    Summary:
    Datetime widget is module based, so datetime widget is used as base for 
efl_ui_clock and merged dayselector/clock features into efl_ui_clock.
    Added day selection and seconds support in efl_ui_clock.
     Added clock features like auto updation of time, stop timer etc in 
efl_ui_clock.
     Added API to enable/disable edit_mode. efl_ui_clock can be configurable to 
display either only day/date/time or display any two of them or display all 
three.
    Added efl_ui_clock.c and test_ui_clock.c. Theme and Module is added in 
another patch by Amitesh.
    
    Original author is Yeshwanth <[email protected]>. I have polished 
this patch a bit and make it compatible with current EFL code.
    
    Test Plan: test_ui_clock
    
    Reviewers: bu5hm4n, tasn, yashu21985, jpeg, cedric, raster
    
    Subscribers: CHAN, woohyun
    
    Differential Revision: https://phab.enlightenment.org/D3938
---
 config/default/base.src.in                |    4 +-
 config/mobile/base.src.in                 |    4 +-
 config/standard/base.src.in               |    4 +-
 src/Makefile_Elementary.am                |    3 +
 src/bin/elementary/Makefile.am            |    1 +
 src/bin/elementary/test.c                 |    2 +
 src/bin/elementary/test_ui_clock.c        |  117 +++
 src/lib/elementary/Elementary.h           |    1 +
 src/lib/elementary/efl_ui_clock.c         | 1189 +++++++++++++++++++++++++++++
 src/lib/elementary/efl_ui_clock.eo        |  260 +++++++
 src/lib/elementary/efl_ui_clock.h         |  204 +++++
 src/lib/elementary/efl_ui_clock_private.h |  130 ++++
 src/lib/elementary/elm_config.c           |    4 +
 13 files changed, 1917 insertions(+), 6 deletions(-)

diff --git a/config/default/base.src.in b/config/default/base.src.in
index 90188f3..9f27fd4 100644
--- a/config/default/base.src.in
+++ b/config/default/base.src.in
@@ -1,5 +1,5 @@
 group "Elm_Config" struct {
-  value "config_version" int: 131084;
+  value "config_version" int: 131085;
   value "engine" string: "";
   value "vsync" uchar: 0;
   value "thumbscroll_enable" uchar: 1;
@@ -39,7 +39,7 @@ group "Elm_Config" struct {
   value "finger_size" int: 10;
   value "fps" double: 60.0;
   value "theme" string: "default";
-  value "modules" string: 
"prefs>prefs_iface:access_output>access/api:datetime_input_ctxpopup>datetime/api";
+  value "modules" string: 
"prefs>prefs_iface:access_output>access/api:datetime_input_ctxpopup>datetime/api:clock_input_ctxpopup>clock/api";
   value "tooltip_delay" double: 1.0;
   value "cursor_engine_only" uchar: 0;
   value "focus_highlight_enable" uchar: 0;
diff --git a/config/mobile/base.src.in b/config/mobile/base.src.in
index 5619970..fedba06 100644
--- a/config/mobile/base.src.in
+++ b/config/mobile/base.src.in
@@ -1,5 +1,5 @@
 group "Elm_Config" struct {
-  value "config_version" int: 131084;
+  value "config_version" int: 131085;
   value "engine" string: "";
   value "vsync" uchar: 0;
   value "thumbscroll_enable" uchar: 1;
@@ -39,7 +39,7 @@ group "Elm_Config" struct {
   value "finger_size" int: 40;
   value "fps" double: 60.0;
   value "theme" string: "default";
-  value "modules" string: 
"prefs>prefs_iface:access_output>access/api:datetime_input_ctxpopup>datetime/api";
+  value "modules" string: 
"prefs>prefs_iface:access_output>access/api:datetime_input_ctxpopup>datetime/api:clock_input_ctxpopup>clock/api";
   value "tooltip_delay" double: 1.0;
   value "cursor_engine_only" uchar: 0;
   value "focus_highlight_enable" uchar: 0;
diff --git a/config/standard/base.src.in b/config/standard/base.src.in
index 849185f..b201a3e 100644
--- a/config/standard/base.src.in
+++ b/config/standard/base.src.in
@@ -1,5 +1,5 @@
 group "Elm_Config" struct {
-  value "config_version" int: 131084;
+  value "config_version" int: 131085;
   value "engine" string: "";
   value "vsync" uchar: 0;
   value "thumbscroll_enable" uchar: 0;
@@ -39,7 +39,7 @@ group "Elm_Config" struct {
   value "finger_size" int: 10;
   value "fps" double: 60.0;
   value "theme" string: "default";
-  value "modules" string: 
"prefs>prefs_iface:access_output>access/api:datetime_input_ctxpopup>datetime/api";
+  value "modules" string: 
"prefs>prefs_iface:access_output>access/api:datetime_input_ctxpopup>datetime/api:clock_input_ctxpopup>clock/api";
   value "tooltip_delay" double: 1.0;
   value "cursor_engine_only" uchar: 0;
   value "focus_highlight_enable" uchar: 0;
diff --git a/src/Makefile_Elementary.am b/src/Makefile_Elementary.am
index dd78134..d2beac4 100644
--- a/src/Makefile_Elementary.am
+++ b/src/Makefile_Elementary.am
@@ -121,6 +121,7 @@ elm_public_eolian_files = \
 # Private classes (not exposed or shipped)
 elm_private_eolian_files = \
        lib/elementary/efl_ui_internal_text_interactive.eo \
+       lib/elementary/efl_ui_clock.eo \
        $(NULL)
 
 # Legacy classes - not part of public EO API
@@ -662,6 +663,7 @@ lib_elementary_libelementary_la_SOURCES = \
        lib/elementary/efl_ui_grid_static.c \
        lib/elementary/efl_ui_grid_private.h \
        lib/elementary/efl_ui_text.c \
+       lib/elementary/efl_ui_clock.c \
        $(NULL)
 
 
@@ -823,6 +825,7 @@ bin/elementary/test_tooltip.c \
 bin/elementary/test_transit.c \
 bin/elementary/test_transit_bezier.c \
 bin/elementary/test_ui_box.c \
+bin/elementary/test_ui_clock.c \
 bin/elementary/test_ui_grid.c \
 bin/elementary/test_video.c \
 bin/elementary/test_weather.c \
diff --git a/src/bin/elementary/Makefile.am b/src/bin/elementary/Makefile.am
index 8f64a68..3bb7ea9 100644
--- a/src/bin/elementary/Makefile.am
+++ b/src/bin/elementary/Makefile.am
@@ -125,6 +125,7 @@ test_toolbar.c \
 test_tooltip.c \
 test_transit.c \
 test_transit_bezier.c \
+test_ui_clock.c \
 test_video.c \
 test_weather.c \
 test_web.c \
diff --git a/src/bin/elementary/test.c b/src/bin/elementary/test.c
index 0c3fa6c..36f2e14 100644
--- a/src/bin/elementary/test.c
+++ b/src/bin/elementary/test.c
@@ -254,6 +254,7 @@ void test_naviframe3(void *data, Evas_Object *obj, void 
*event_info);
 void test_naviframe_complex(void *data, Evas_Object *obj, void *event_info);
 //void test_factory(void *data, Evas_Object *obj, void *event_info);
 void test_datetime(void *data, Evas_Object *obj, void *event_info);
+void test_ui_clock(void *data, Evas_Object *obj, void *event_info);
 void test_popup(void *data, Evas_Object *obj, void *event_info);
 void test_dayselector(void *data, Evas_Object *obj, void *event_info);
 void test_image(void *data, Evas_Object *obj, void *event_info);
@@ -917,6 +918,7 @@ add_tests:
    ADD_TEST(NULL, "Times & Dates", "Clock Edit 2", test_clock_edit2);
    ADD_TEST(NULL, "Times & Dates", "Clock Pause", test_clock_pause);
    ADD_TEST(NULL, "Times & Dates", "Datetime", test_datetime);
+   ADD_TEST(NULL, "Times & Dates", "Ui.Clock", test_ui_clock);
 
    //------------------------------//
    ADD_TEST(NULL, "Text", "Label", test_label);
diff --git a/src/bin/elementary/test_ui_clock.c 
b/src/bin/elementary/test_ui_clock.c
new file mode 100644
index 0000000..47f7f6c
--- /dev/null
+++ b/src/bin/elementary/test_ui_clock.c
@@ -0,0 +1,117 @@
+#ifdef HAVE_CONFIG_H
+#include "elementary_config.h"
+#endif
+#include <Elementary.h>
+
+/* A simple test, just displaying clock in its default format */
+
+Evas_Object *dt1, *dt2, *dt3, *dt4;
+
+static void
+_changed_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void 
*event_info EINA_UNUSED)
+{
+   printf("Clock value is changed\n");
+}
+
+static void
+_bt_clicked(void *data EINA_UNUSED, Evas_Object *obj, void *event_info 
EINA_UNUSED)
+{
+   time_t t;
+   struct tm new_time;
+
+   t = time(NULL);
+   localtime_r(&t, &new_time);
+
+   new_time.tm_year = 85;
+   new_time.tm_mon = 9;
+   new_time.tm_mday = 26;
+   new_time.tm_hour = 9;
+   new_time.tm_min = 0;
+   efl_ui_clock_field_visible_set(dt1, EFL_UI_CLOCK_TYPE_HOUR, EINA_TRUE);
+   efl_ui_clock_field_visible_set(dt1, EFL_UI_CLOCK_TYPE_MINUTE, EINA_TRUE);
+   efl_ui_clock_field_visible_set(dt1, EFL_UI_CLOCK_TYPE_AMPM, EINA_TRUE);
+   efl_ui_clock_field_visible_set(dt1, EFL_UI_CLOCK_TYPE_SECOND, EINA_TRUE);
+   efl_ui_clock_field_visible_set(dt1, EFL_UI_CLOCK_TYPE_DAY, EINA_TRUE);
+
+   efl_ui_clock_value_set(dt1, &new_time);
+   elm_object_disabled_set(dt1, EINA_TRUE);
+
+   elm_object_disabled_set(obj, EINA_TRUE);
+   evas_object_del(dt2);
+   evas_object_del(dt3);
+   dt2 = dt3 = NULL;
+}
+
+void
+test_ui_clock(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void 
*event_info EINA_UNUSED)
+{
+   Evas_Object *win, *bx, *bt, *lb;
+
+   win = elm_win_util_standard_add("ui_clock", "ui_clock");
+   elm_win_autodel_set(win, EINA_TRUE);
+
+   bx = elm_box_add(win);
+   evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, bx);
+   elm_box_horizontal_set(bx, EINA_FALSE);
+   evas_object_show(bx);
+   evas_object_size_hint_min_set(bx, 360, 240);
+
+   dt1 = efl_add(EFL_UI_CLOCK_CLASS, bx);
+   evas_object_size_hint_weight_set(dt1, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(dt1, EVAS_HINT_FILL, 0.5);
+   efl_ui_clock_field_visible_set(dt1, EFL_UI_CLOCK_TYPE_HOUR, EINA_FALSE);
+   efl_ui_clock_field_visible_set(dt1, EFL_UI_CLOCK_TYPE_MINUTE, EINA_FALSE);
+   efl_ui_clock_field_visible_set(dt1, EFL_UI_CLOCK_TYPE_AMPM, EINA_FALSE);
+   efl_ui_clock_field_visible_set(dt1, EFL_UI_CLOCK_TYPE_SECOND, EINA_FALSE);
+   efl_ui_clock_field_visible_set(dt1, EFL_UI_CLOCK_TYPE_DAY, EINA_FALSE);
+   efl_ui_clock_pause_set(dt1, EINA_TRUE);
+   elm_box_pack_end(bx, dt1);
+   evas_object_smart_callback_add(dt1, "changed", _changed_cb, NULL);
+   evas_object_show(dt1);
+
+   dt2 = efl_add(EFL_UI_CLOCK_CLASS, bx);
+   evas_object_size_hint_weight_set(dt2, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(dt2, EVAS_HINT_FILL, 0.5);
+   efl_ui_clock_field_visible_set(dt2, EFL_UI_CLOCK_TYPE_YEAR, EINA_FALSE);
+   efl_ui_clock_field_visible_set(dt2, EFL_UI_CLOCK_TYPE_MONTH, EINA_FALSE);
+   efl_ui_clock_field_visible_set(dt2, EFL_UI_CLOCK_TYPE_DATE, EINA_FALSE);
+   efl_ui_clock_field_visible_set(dt1, EFL_UI_CLOCK_TYPE_SECOND, EINA_FALSE);
+   elm_box_pack_end(bx, dt2);
+   efl_ui_clock_pause_set(dt2, EINA_TRUE);
+   elm_object_disabled_set(dt2, EINA_TRUE);
+   evas_object_show(dt2);
+
+   dt3 = efl_add(EFL_UI_CLOCK_CLASS, bx);
+   evas_object_size_hint_weight_set(dt3, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(dt3, EVAS_HINT_FILL, 0.5);
+   elm_box_pack_end(bx, dt3);
+   evas_object_show(dt3);
+
+   //editable
+   lb = efl_add(ELM_LABEL_CLASS, bx);
+   elm_object_text_set(lb,
+                       "<b>Editable Clock:</b>"
+                       );
+   evas_object_size_hint_weight_set(lb, 0.0, 0.0);
+   evas_object_size_hint_align_set(lb, 0, EVAS_HINT_FILL);
+   evas_object_size_hint_min_set(lb, 100, 25);
+   elm_box_pack_end(bx, lb);
+   evas_object_show(lb);
+
+   dt4 = efl_add(EFL_UI_CLOCK_CLASS, bx);
+   evas_object_size_hint_weight_set(dt4, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(dt4, EVAS_HINT_FILL, 0.5);
+   efl_ui_clock_edit_mode_set(dt4, EINA_TRUE);
+   efl_ui_clock_pause_set(dt4, EINA_TRUE);
+   elm_box_pack_end(bx, dt4);
+   evas_object_show(dt4);
+
+   bt = elm_button_add(win);
+   elm_object_text_set(bt, "Back to the future...");
+   evas_object_smart_callback_add(bt, "clicked", _bt_clicked, NULL);
+   elm_box_pack_end(bx, bt);
+   evas_object_show(bt);
+
+   evas_object_show(win);
+}
diff --git a/src/lib/elementary/Elementary.h b/src/lib/elementary/Elementary.h
index 9de8202..5b956a3 100644
--- a/src/lib/elementary/Elementary.h
+++ b/src/lib/elementary/Elementary.h
@@ -263,6 +263,7 @@ EAPI extern Elm_Version *elm_version;
 # include <efl_ui_text_interactive.eo.h>
 # include <efl_ui_text.eo.h>
 # include <efl_ui_text_editable.eo.h>
+# include <efl_ui_clock.eo.h>
 #endif
 
 /* include deprecated calls last of all */
diff --git a/src/lib/elementary/efl_ui_clock.c 
b/src/lib/elementary/efl_ui_clock.c
new file mode 100644
index 0000000..6c2d864
--- /dev/null
+++ b/src/lib/elementary/efl_ui_clock.c
@@ -0,0 +1,1189 @@
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#endif
+
+#define ELM_INTERFACE_ATSPI_ACCESSIBLE_PROTECTED
+
+#include <Elementary.h>
+#include "elm_priv.h"
+#include <efl_ui_clock.h>
+#include <efl_ui_clock_private.h>
+
+#define MY_CLASS EFL_UI_CLOCK_CLASS
+
+#define MY_CLASS_NAME "Efl_Ui_Clock"
+#define MY_CLASS_NAME_LEGACY "efl_ui_clock"
+
+#ifdef HAVE_LOCALE_H
+# include <locale.h>
+#endif
+
+#ifdef HAVE_LANGINFO_H
+# include <langinfo.h>
+#endif
+
+#define MAX_SEPARATOR_LEN              6
+#define MIN_DAYS_IN_MONTH              28
+#define BUFFER_SIZE                    1024
+
+/* interface between EDC & C code (field & signal names). values 0 to
+ * EFL_UI_CLOCK_TYPE_COUNT are in the valid range, and must get in the
+ * place of "%d".
+ */
+#define EDC_CLOCK_FOCUSIN_SIG_STR   "elm,action,focus"
+#define EDC_CLOCK_FOCUSOUT_SIG_STR  "elm,action,unfocus"
+#define EDC_PART_FIELD_STR             "field%d"
+#define EDC_PART_SEPARATOR_STR         "separator%d"
+#define EDC_PART_FIELD_ENABLE_SIG_STR  "field%d,enable"
+#define EDC_PART_FIELD_DISABLE_SIG_STR "field%d,disable"
+
+/* struct tm does not define the fields in the order year, month,
+ * date, hour, minute. values are reassigned to an array for easy
+ * handling.
+ */
+#define CLOCK_TM_ARRAY(intptr, tmptr) \
+  int *intptr[] = {                      \
+     &(tmptr)->tm_year,                  \
+     &(tmptr)->tm_mon,                   \
+     &(tmptr)->tm_mday,                  \
+     &(tmptr)->tm_hour,                  \
+     &(tmptr)->tm_min,                  \
+     &(tmptr)->tm_sec,                  \
+     &(tmptr)->tm_wday,                  \
+     &(tmptr)->tm_hour}
+
+// default limits for individual fields
+static Format_Map mapping[EFL_UI_CLOCK_TYPE_COUNT] = {
+   [EFL_UI_CLOCK_TYPE_YEAR] = { "Yy", -1, -1, "" },
+   [EFL_UI_CLOCK_TYPE_MONTH] = { "mbBh", 0, 11, "" },
+   [EFL_UI_CLOCK_TYPE_DATE] = { "de", 1, 31, "" },
+   [EFL_UI_CLOCK_TYPE_HOUR] = { "IHkl", 0, 23, "" },
+   [EFL_UI_CLOCK_TYPE_MINUTE] = { "M", 0, 59, "" },
+   [EFL_UI_CLOCK_TYPE_SECOND] = { "S", 0, 59, "" },
+   [EFL_UI_CLOCK_TYPE_DAY] = { "Aa", 0, 6, "" },
+   [EFL_UI_CLOCK_TYPE_AMPM] = { "pP", 0, 1, "" }
+};
+
+static const char *multifield_formats = "cxXrRTDF";
+static const char *ignore_separators = "()";
+static Clock_Mod_Api *dt_mod = NULL;
+
+static const char SIG_CHANGED[] = "changed";
+static const Evas_Smart_Cb_Description _smart_callbacks[] = {
+   {SIG_CHANGED, ""},
+   {SIG_WIDGET_LANG_CHANGED, ""}, /**< handled by elm_widget */
+   {SIG_WIDGET_ACCESS_CHANGED, ""}, /**< handled by elm_widget */
+   {SIG_LAYOUT_FOCUSED, ""}, /**< handled by elm_layout */
+   {SIG_LAYOUT_UNFOCUSED, ""}, /**< handled by elm_layout */
+   {NULL, NULL}
+};
+
+static Clock_Mod_Api *
+_dt_mod_init()
+{
+   Elm_Module *mod = NULL;
+
+   if (!(mod = _elm_module_find_as("clock/api"))) return NULL;
+
+   mod->api = malloc(sizeof(Clock_Mod_Api));
+   if (!mod->api) return NULL;
+
+   ((Clock_Mod_Api *)(mod->api))->obj_hook =
+     _elm_module_symbol_get(mod, "obj_hook");
+   ((Clock_Mod_Api *)(mod->api))->obj_unhook =
+     _elm_module_symbol_get(mod, "obj_unhook");
+   ((Clock_Mod_Api *)(mod->api))->obj_hide =
+     _elm_module_symbol_get(mod, "obj_hide");
+   ((Clock_Mod_Api *)(mod->api))->field_create =
+     _elm_module_symbol_get(mod, "field_create");
+   ((Clock_Mod_Api *)(mod->api))->field_value_display =
+     _elm_module_symbol_get(mod, "field_value_display");
+
+   return mod->api;
+}
+
+static void
+_field_list_display(Evas_Object *obj)
+{
+   Clock_Field *field;
+   unsigned int idx = 0;
+
+   EFL_UI_CLOCK_DATA_GET(obj, sd);
+
+   if (!dt_mod || !dt_mod->field_value_display) return;
+
+   for (idx = 0; idx < EFL_UI_CLOCK_TYPE_COUNT; idx++)
+     {
+        field = sd->field_list + idx;
+        if (field->fmt_exist && field->visible)
+          dt_mod->field_value_display(sd->mod_data, field->item_obj);
+     }
+}
+
+// FIXME: provide nl_langinfo on Windows if possible
+// returns expanded format string for corresponding multi-field format 
character
+static char *
+_expanded_fmt_str_get(char ch)
+{
+   char *exp_fmt = "";
+   switch (ch)
+     {
+      case 'c':
+#if defined(HAVE_LANGINFO_H) || defined (HAVE_EVIL)
+        exp_fmt = nl_langinfo(D_T_FMT);
+#else
+        exp_fmt = "";
+#endif
+        break;
+
+      case 'x':
+#if defined(HAVE_LANGINFO_H) || defined (HAVE_EVIL)
+        exp_fmt = nl_langinfo(D_FMT);
+#else
+        exp_fmt = "";
+#endif
+        break;
+
+      case 'X':
+#if defined(HAVE_LANGINFO_H) || defined (HAVE_EVIL)
+        exp_fmt = nl_langinfo(T_FMT);
+#else
+        exp_fmt = "";
+#endif
+        break;
+
+      case 'r':
+#if defined(HAVE_LANGINFO_H) || defined (HAVE_EVIL)
+        exp_fmt = nl_langinfo(T_FMT_AMPM);
+#else
+        exp_fmt = "";
+#endif
+        break;
+
+      case 'R':
+        exp_fmt = "%H:%M";
+        break;
+
+      case 'T':
+        exp_fmt = "%H:%M:%S";
+        break;
+
+      case 'D':
+        exp_fmt = "%m/%d/%y";
+        break;
+
+      case 'F':
+        exp_fmt = "%Y-%m-%d";
+        break;
+
+      default:
+        exp_fmt = "";
+        break;
+     }
+
+   return exp_fmt;
+}
+
+static void
+_expand_format(char *dt_fmt)
+{
+   char *ptr, *expanded_fmt, ch;
+   unsigned int idx = 0, len = 0;
+   char buf[EFL_UI_CLOCK_MAX_FORMAT_LEN] = {0, };
+   Eina_Bool fmt_char = EINA_FALSE;
+
+   ptr = dt_fmt;
+   while ((ch = *ptr))
+     {
+        if ((fmt_char) && (strchr(multifield_formats, ch)))
+          {
+             /* replace the multi-field format characters with
+              * corresponding expanded format */
+             expanded_fmt = _expanded_fmt_str_get(ch);
+             len = strlen(expanded_fmt);
+             buf[--idx] = 0;
+             strncat(buf, expanded_fmt, len);
+             idx += len;
+          }
+        else buf[idx++] = ch;
+
+        if (ch == '%') fmt_char = EINA_TRUE;
+        else fmt_char = EINA_FALSE;
+
+        ptr++;
+     }
+
+   buf[idx] = 0;
+   strncpy(dt_fmt, buf, EFL_UI_CLOCK_MAX_FORMAT_LEN);
+}
+
+static void
+_field_list_arrange(Evas_Object *obj)
+{
+   Clock_Field *field;
+   char buf[BUFFER_SIZE];
+   int idx;
+   Eina_Bool freeze;
+
+   EFL_UI_CLOCK_DATA_GET(obj, sd);
+
+   freeze = sd->freeze_sizing;
+   sd->freeze_sizing = EINA_TRUE;
+   for (idx = 0; idx < EFL_UI_CLOCK_TYPE_COUNT; idx++)
+     {
+        field = sd->field_list + idx;
+        snprintf(buf, sizeof(buf), EDC_PART_FIELD_STR, field->location);
+
+        if (field->visible && field->fmt_exist)
+          {
+             evas_object_hide(elm_layout_content_unset(obj, buf));
+             elm_layout_content_set(obj, buf, field->item_obj);
+          }
+        else
+          evas_object_hide(elm_layout_content_unset(obj, buf));
+     }
+   sd->freeze_sizing = freeze;
+
+   elm_layout_sizing_eval(obj);
+   _field_list_display(obj);
+}
+
+static unsigned int
+_parse_format(Evas_Object *obj,
+              char *fmt_ptr)
+{
+   Eina_Bool fmt_parsing = EINA_FALSE, sep_parsing = EINA_FALSE,
+             sep_lookup = EINA_FALSE;
+   unsigned int len = 0, idx = 0, location = 0;
+   char separator[MAX_SEPARATOR_LEN];
+   Clock_Field *field = NULL;
+   char cur;
+
+   EFL_UI_CLOCK_DATA_GET(obj, sd);
+
+   while ((cur = *fmt_ptr))
+     {
+        if (fmt_parsing)
+          {
+             if (cur == '_' || cur == '-' || cur == '0' || cur == '^' || cur 
== '#')
+               {
+                  fmt_ptr++;
+                  continue;
+               }
+             fmt_parsing = EINA_FALSE;
+             for (idx = 0; idx < EFL_UI_CLOCK_TYPE_COUNT; idx++)
+               {
+                  if (strchr(mapping[idx].fmt_char, cur))
+                    {
+                       field = sd->field_list + idx;
+                       /* ignore the fields already have or disabled
+                        * valid formats, means already parsed &
+                        * repeated, ignore. */
+                       if (field->location != -1) break;
+                       field->fmt[1] = cur;
+                       field->fmt_exist = EINA_TRUE;
+                       field->location = location++;
+                       sep_lookup = EINA_TRUE;
+                       len = 0;
+                       break;
+                    }
+               }
+          }
+        if (cur == '%')
+          {
+             fmt_parsing = EINA_TRUE;
+             sep_parsing = EINA_FALSE;
+             // set the separator to previous field
+             separator[len] = 0;
+             if (field) eina_stringshare_replace(&field->separator, separator);
+          }
+        // ignore the set of chars (global, field specific) as field separators
+        if (sep_parsing &&
+            (len < MAX_SEPARATOR_LEN - 1) &&
+            (field->type != EFL_UI_CLOCK_TYPE_AMPM) &&
+            (!strchr(ignore_separators, cur)) &&
+            (!strchr(mapping[idx].ignore_sep, cur)))
+          separator[len++] = cur;
+        if (sep_lookup) sep_parsing = EINA_TRUE;
+        sep_lookup = EINA_FALSE;
+        fmt_ptr++;
+     }
+   // return the number of valid fields parsed.
+   return location;
+}
+
+static void
+_reload_format(Evas_Object *obj)
+{
+   unsigned int idx, field_count;
+   Clock_Field *field;
+   char buf[BUFFER_SIZE];
+   char *dt_fmt;
+
+   EFL_UI_CLOCK_DATA_GET(obj, sd);
+   ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
+
+   // FIXME: provide nl_langinfo on Windows if possible
+   // fetch the default format from Libc.
+   if (!sd->user_format)
+#if defined(HAVE_LANGINFO_H) || defined (HAVE_EVIL)
+     strncpy(sd->format, nl_langinfo(D_T_FMT), EFL_UI_CLOCK_MAX_FORMAT_LEN);
+#else
+     strncpy(sd->format, "", EFL_UI_CLOCK_MAX_FORMAT_LEN);
+#endif
+   sd->format[EFL_UI_CLOCK_MAX_FORMAT_LEN - 1] = '\0';
+
+   dt_fmt = (char *)malloc(EFL_UI_CLOCK_MAX_FORMAT_LEN);
+   if (!dt_fmt) return;
+
+   strncpy(dt_fmt, sd->format, EFL_UI_CLOCK_MAX_FORMAT_LEN);
+
+   _expand_format(dt_fmt);
+
+   // reset all the fields to disable state
+   sd->enabled_field_count = 0;
+   for (idx = 0; idx < EFL_UI_CLOCK_TYPE_COUNT; idx++)
+     {
+        field = sd->field_list + idx;
+        field->fmt_exist = EINA_FALSE;
+        field->location = -1;
+     }
+
+   field_count = _parse_format(obj, dt_fmt);
+   free(dt_fmt);
+
+   for (idx = 0; idx < EFL_UI_CLOCK_TYPE_COUNT; idx++)
+     {
+        field = sd->field_list + idx;
+        if (field->fmt_exist && field->visible)
+          sd->enabled_field_count++;
+     }
+
+   // assign locations to disabled fields for uniform usage
+   for (idx = 0; idx < EFL_UI_CLOCK_TYPE_COUNT; idx++)
+     {
+        field = sd->field_list + idx;
+        if (field->location == -1) field->location = field_count++;
+
+        if (field->fmt_exist && field->visible)
+          {
+             snprintf(buf, sizeof(buf), EDC_PART_FIELD_ENABLE_SIG_STR,
+                      field->location);
+             elm_layout_signal_emit(obj, buf, "elm");
+          }
+        else
+          {
+             snprintf(buf, sizeof(buf), EDC_PART_FIELD_DISABLE_SIG_STR,
+                      field->location);
+             elm_layout_signal_emit(obj, buf, "elm");
+          }
+        snprintf
+          (buf, sizeof(buf), EDC_PART_SEPARATOR_STR, (field->location + 1));
+        elm_layout_text_set(obj, buf, field->separator);
+     }
+
+   edje_object_message_signal_process(wd->resize_obj);
+   _field_list_arrange(obj);
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_clock_elm_widget_translate(Eo *obj, Efl_Ui_Clock_Data *sd)
+{
+   if (!sd->user_format) _reload_format(obj);
+   else _field_list_display(obj);
+
+   elm_obj_widget_translate(efl_super(obj, MY_CLASS));
+
+   return EINA_TRUE;
+}
+
+static Eina_List *
+_clock_items_get(const Evas_Object *obj)
+{
+   Eina_List *items = NULL;
+   Clock_Field *field;
+   unsigned int idx;
+   Clock_Field *sorted_fields[EFL_UI_CLOCK_TYPE_COUNT];
+
+   EFL_UI_CLOCK_DATA_GET(obj, sd);
+
+   for (idx = 0; idx < EFL_UI_CLOCK_TYPE_COUNT; idx++)
+     {
+        field = sd->field_list + idx;
+        sorted_fields[field->location] = field;
+     }
+
+   for (idx = 0; idx < EFL_UI_CLOCK_TYPE_COUNT; idx++)
+     {
+        field = sorted_fields[idx];
+        if (field->fmt_exist && field->visible)
+          items = eina_list_append(items, field->item_obj);
+     }
+
+   // ACCESS
+   if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
+     items = eina_list_append(items, sd->access_obj);
+
+   return items;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_clock_elm_widget_focus_next_manager_is(Eo *obj EINA_UNUSED, 
Efl_Ui_Clock_Data *_pd EINA_UNUSED)
+{
+   return EINA_TRUE;
+}
+
+EOLIAN static void
+_efl_ui_clock_pause_set(Eo *obj EINA_UNUSED, Efl_Ui_Clock_Data *sd, Eina_Bool 
paused)
+{
+   paused = !!paused;
+   if (sd->paused == paused)
+     return;
+   sd->paused = paused;
+   if (paused)
+     ecore_timer_freeze(sd->ticker);
+   else
+     ecore_timer_thaw(sd->ticker);
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_clock_pause_get(Eo *obj EINA_UNUSED, Efl_Ui_Clock_Data *sd)
+{
+   return sd->paused;
+}
+
+EOLIAN static void
+_efl_ui_clock_edit_mode_set(Eo *obj EINA_UNUSED, Efl_Ui_Clock_Data *sd, 
Eina_Bool edit_mode)
+{
+   sd->edit_mode = edit_mode;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_clock_edit_mode_get(Eo *obj EINA_UNUSED, Efl_Ui_Clock_Data *sd)
+{
+   return sd->edit_mode;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_clock_elm_widget_focus_next(Eo *obj, Efl_Ui_Clock_Data *_pd 
EINA_UNUSED, Elm_Focus_Direction dir, Evas_Object **next, Elm_Object_Item 
**next_item)
+{
+   const Eina_List *items;
+   Eina_List *(*list_free)(Eina_List *list);
+   void *(*list_data_get)(const Eina_List *list);
+
+   Eina_Bool int_ret;
+
+   if ((items = elm_widget_focus_custom_chain_get(obj)))
+     {
+        list_data_get = eina_list_data_get;
+        list_free = NULL;
+     }
+   else
+     {
+        items = _clock_items_get(obj);
+        list_data_get = eina_list_data_get;
+        list_free = eina_list_free;
+        if (!items) return EINA_FALSE;
+     }
+
+   int_ret = elm_widget_focus_list_next_get(obj, items, list_data_get, dir, 
next, next_item);
+   if (list_free) list_free((Eina_List *)items);
+
+   return int_ret;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_clock_elm_widget_on_focus(Eo *obj, Efl_Ui_Clock_Data *sd, 
Elm_Object_Item *item EINA_UNUSED)
+{
+   Eina_Bool int_ret = EINA_FALSE;
+
+   int_ret = elm_obj_widget_on_focus(efl_super(obj, MY_CLASS), NULL);
+   if (!int_ret) return EINA_FALSE;
+
+   if (!elm_widget_focus_get(obj))
+     {
+        if ((dt_mod) && (dt_mod->obj_hide))
+          dt_mod->obj_hide(sd->mod_data);
+     }
+
+   return EINA_TRUE;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_clock_elm_widget_disable(Eo *obj, Efl_Ui_Clock_Data *sd)
+{
+   Clock_Field *field;
+   unsigned int idx = 0;
+   Eina_Bool int_ret = EINA_FALSE;
+
+   int_ret = elm_obj_widget_disable(efl_super(obj, MY_CLASS));
+   if (!int_ret) return EINA_FALSE;
+
+   for (idx = 0; idx < EFL_UI_CLOCK_TYPE_COUNT; idx++)
+     {
+        field = sd->field_list + idx;
+        elm_object_disabled_set(field->item_obj, elm_object_disabled_get(obj));
+     }
+   return EINA_TRUE;
+}
+
+EOLIAN static void
+_efl_ui_clock_elm_layout_sizing_eval(Eo *obj, Efl_Ui_Clock_Data *sd)
+{
+   Evas_Coord minw = -1, minh = -1;
+
+   if (sd->freeze_sizing) return;
+
+   ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
+
+   if (sd->enabled_field_count)
+     elm_coords_finger_size_adjust(sd->enabled_field_count, &minw, 1, &minh);
+
+   edje_object_size_min_restricted_calc
+     (wd->resize_obj, &minw, &minh, minw, minh);
+   evas_object_size_hint_min_set(obj, minw, minh);
+   evas_object_size_hint_max_set(obj, -1, -1);
+}
+
+EOLIAN static Elm_Theme_Apply
+_efl_ui_clock_elm_widget_theme_apply(Eo *obj, Efl_Ui_Clock_Data *sd)
+{
+   Elm_Theme_Apply int_ret = ELM_THEME_APPLY_FAILED;
+
+   Clock_Field *field;
+   char buf[BUFFER_SIZE];
+   unsigned int idx;
+
+   ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_FALSE);
+
+   int_ret = elm_obj_widget_theme_apply(efl_super(obj, MY_CLASS));
+   if (!int_ret) return ELM_THEME_APPLY_FAILED;
+
+   if ((!dt_mod) || (!dt_mod->field_value_display)) return EINA_TRUE;
+
+   for (idx = 0; idx < EFL_UI_CLOCK_TYPE_COUNT; idx++)
+     {
+        field = sd->field_list + idx;
+        if (field->fmt_exist && field->visible)
+          {
+             snprintf(buf, sizeof(buf), EDC_PART_FIELD_ENABLE_SIG_STR,
+                      field->location);
+             elm_layout_signal_emit(obj, buf, "elm");
+
+             snprintf
+               (buf, sizeof(buf), EDC_PART_SEPARATOR_STR, field->location);
+             elm_layout_text_set(obj, buf, field->separator);
+
+             dt_mod->field_value_display(sd->mod_data, field->item_obj);
+          }
+        else
+          {
+             snprintf(buf, sizeof(buf), EDC_PART_FIELD_DISABLE_SIG_STR,
+                      field->location);
+             elm_layout_signal_emit(obj, buf, "elm");
+          }
+     }
+
+   edje_object_message_signal_process(wd->resize_obj);
+   elm_layout_sizing_eval(obj);
+
+   return int_ret;
+}
+
+static int
+_max_days_get(int year,
+              int month)
+{
+   struct tm time1;
+   time_t t;
+   int day;
+
+   t = time(NULL);
+   localtime_r(&t, &time1);
+   time1.tm_year = year;
+   time1.tm_mon = month;
+   for (day = MIN_DAYS_IN_MONTH; day <= 
mapping[EFL_UI_CLOCK_TYPE_DATE].def_max;
+        day++)
+     {
+        time1.tm_mday = day;
+        mktime(&time1);
+        /* To restrict month wrapping because of summer time in some locales,
+        * ignore day light saving mode in mktime(). */
+        time1.tm_isdst = -1;
+        if (time1.tm_mday == 1) break;
+     }
+   day--;
+
+   return day;
+}
+
+static Eina_Bool
+_date_cmp(const struct tm *time1,
+          const struct tm *time2)
+{
+   unsigned int idx;
+
+   const CLOCK_TM_ARRAY(timearr1, time1);
+   const CLOCK_TM_ARRAY(timearr2, time2);
+
+   for (idx = 0; idx < EFL_UI_CLOCK_TYPE_COUNT; idx++)
+     {
+        if (*timearr1[idx] != *timearr2[idx])
+          return EINA_FALSE;
+     }
+
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_field_cmp(Efl_Ui_Clock_Type field_type,
+          struct tm *time1,
+          struct tm *time2)
+{
+   CLOCK_TM_ARRAY(timearr1, time1);
+   CLOCK_TM_ARRAY(timearr2, time2);
+
+   if (*timearr1[field_type] != *timearr2[field_type])
+     return EINA_FALSE;
+   else
+     return EINA_TRUE;
+}
+
+// validates curr_time/min_limt/max_limit according to the newly set value
+static void
+_validate_clock_limits(struct tm *time1,
+                          struct tm *time2,
+                          Eina_Bool swap)
+{
+   struct tm *t1, *t2;
+   unsigned int idx;
+
+   if (!time1 || !time2) return;
+
+   t1 = (swap) ? time2 : time1;
+   t2 = (swap) ? time1 : time2;
+
+   CLOCK_TM_ARRAY(timearr1, time1);
+   CLOCK_TM_ARRAY(timearr2, time2);
+   for (idx = 0; idx < EFL_UI_CLOCK_TYPE_COUNT - 1; idx++)
+     {
+        if (*timearr1[idx] < *timearr2[idx])
+          {
+             memcpy(t1, t2, sizeof(struct tm));
+             break;
+          }
+        else if (*timearr1[idx] > *timearr2[idx])
+          break;
+     }
+}
+
+static void
+_apply_field_limits(Evas_Object *obj)
+{
+   Clock_Field *field;
+   unsigned int idx = 0;
+   int val;
+
+   EFL_UI_CLOCK_DATA_GET(obj, sd);
+
+   CLOCK_TM_ARRAY(timearr, &sd->curr_time);
+   for (idx = 0; idx < EFL_UI_CLOCK_TYPE_COUNT - 1; idx++)
+     {
+        field = sd->field_list + idx;
+        val = *timearr[idx];
+        if (val < field->min)
+          *timearr[idx] = field->min;
+        else if (val > field->max)
+          *timearr[idx] = field->max;
+     }
+
+   _field_list_display(obj);
+}
+
+static void
+_apply_range_restrictions(struct tm *tim)
+{
+   unsigned int idx;
+   int val, min, max;
+
+   if (!tim) return;
+
+   CLOCK_TM_ARRAY(timearr, tim);
+   for (idx = EFL_UI_CLOCK_TYPE_MONTH; idx < EFL_UI_CLOCK_TYPE_COUNT - 1; 
idx++)
+     {
+        val = *timearr[idx];
+        min = mapping[idx].def_min;
+        max = mapping[idx].def_max;
+        if (idx == EFL_UI_CLOCK_TYPE_DATE)
+          max = _max_days_get(tim->tm_year, tim->tm_mon);
+        if (val < min)
+          *timearr[idx] = min;
+        else if (val > max)
+          *timearr[idx] = max;
+     }
+}
+
+static const char *
+_field_format_get(Evas_Object *obj,
+                  Efl_Ui_Clock_Type field_type)
+{
+   Clock_Field *field;
+
+   if (field_type > EFL_UI_CLOCK_TYPE_DAY) return NULL;
+
+   EFL_UI_CLOCK_DATA_GET(obj, sd);
+
+   field = sd->field_list + field_type;
+
+   return field->fmt;
+}
+
+static void
+_field_limit_get(Evas_Object *obj,
+                 Efl_Ui_Clock_Type field_type,
+                 int *range_min,
+                 int *range_max)
+{
+   int min, max, max_days;
+   Clock_Field *field;
+   unsigned int idx;
+
+   if (field_type > EFL_UI_CLOCK_TYPE_DAY) return;
+
+   EFL_UI_CLOCK_DATA_GET(obj, sd);
+
+   field = sd->field_list + field_type;
+
+   min = field->min;
+   max = field->max;
+
+   CLOCK_TM_ARRAY(curr_timearr, &sd->curr_time);
+   CLOCK_TM_ARRAY(min_timearr, &sd->min_limit);
+   CLOCK_TM_ARRAY(max_timearr, &sd->max_limit);
+
+   for (idx = 0; idx < field->type; idx++)
+     if (*curr_timearr[idx] > *min_timearr[idx]) break;
+   if ((idx == field_type) && (min < *min_timearr[field_type]))
+     min = *min_timearr[field_type];
+   if (field_type == EFL_UI_CLOCK_TYPE_DATE)
+     {
+        max_days = _max_days_get(sd->curr_time.tm_year, sd->curr_time.tm_mon);
+        if (max > max_days) max = max_days;
+     }
+   for (idx = 0; idx < field->type; idx++)
+     if (*curr_timearr[idx] < *max_timearr[idx]) break;
+   if ((idx == field_type) && (max > *max_timearr[field_type]))
+     max = *max_timearr[field_type];
+
+   *range_min = min;
+   *range_max = max;
+}
+
+static void
+_field_list_init(Evas_Object *obj)
+{
+   Clock_Field *field;
+   unsigned int idx;
+   time_t t;
+
+   EFL_UI_CLOCK_DATA_GET(obj, sd);
+
+   t = time(NULL);
+   localtime_r(&t, &sd->curr_time);
+
+   mapping[EFL_UI_CLOCK_TYPE_YEAR].def_min = _elm_config->year_min;
+   mapping[EFL_UI_CLOCK_TYPE_YEAR].def_max = _elm_config->year_max;
+   for (idx = 0; idx < EFL_UI_CLOCK_TYPE_COUNT; idx++)
+     {
+        field = sd->field_list + idx;
+        field->type = EFL_UI_CLOCK_TYPE_YEAR + idx;
+        field->fmt[0] = '%';
+        field->fmt_exist = EINA_FALSE;
+        field->visible = EINA_TRUE;
+        field->min = mapping[idx].def_min;
+        field->max = mapping[idx].def_max;
+     }
+   CLOCK_TM_ARRAY(min_timearr, &sd->min_limit);
+   CLOCK_TM_ARRAY(max_timearr, &sd->max_limit);
+   for (idx = 0; idx < EFL_UI_CLOCK_TYPE_COUNT - 1; idx++)
+     {
+        *min_timearr[idx] = mapping[idx].def_min;
+        *max_timearr[idx] = mapping[idx].def_max;
+     }
+}
+
+static char *
+_access_info_cb(void *data, Evas_Object *obj EINA_UNUSED)
+{
+   char *ret;
+   Eina_Strbuf *buf;
+   buf = eina_strbuf_new();
+
+   EFL_UI_CLOCK_DATA_GET(data, sd);
+   eina_strbuf_append_printf(buf,
+                             "%d year, %d month, %d date, %d hour, %d minute",
+                             sd->curr_time.tm_year, sd->curr_time.tm_mon + 1,
+                             sd->curr_time.tm_mday, sd->curr_time.tm_hour,
+                             sd->curr_time.tm_min);
+
+   ret = eina_strbuf_string_steal(buf);
+   eina_strbuf_free(buf);
+   return ret;
+}
+
+static Eina_Bool
+_ticker(void *data)
+{
+   double t;
+   time_t tt;
+   struct timeval timev;
+   Clock_Field *field;
+
+   EFL_UI_CLOCK_DATA_GET(data, sd);
+
+   tt = time(NULL);
+   localtime_r(&tt, &sd->curr_time);
+
+   if (sd->curr_time.tm_sec > 0)
+     {
+        field = sd->field_list + EFL_UI_CLOCK_TYPE_SECOND;
+        if (field->fmt_exist && field->visible)
+          dt_mod->field_value_display(sd->mod_data, field->item_obj);
+     }
+   else
+     _field_list_display(data);
+
+   gettimeofday(&timev, NULL);
+   t = ((double)(1000000 - timev.tv_usec)) / 1000000.0;
+   sd->ticker = ecore_timer_add(t, _ticker, data);
+
+   return ECORE_CALLBACK_CANCEL;
+}
+
+EOLIAN static void
+_efl_ui_clock_efl_canvas_group_group_add(Eo *obj, Efl_Ui_Clock_Data *priv)
+{
+   Clock_Field *field;
+   int idx;
+
+   efl_canvas_group_add(efl_super(obj, MY_CLASS));
+   elm_widget_sub_object_parent_add(obj);
+
+   // module - initialise module for clock
+   if (!dt_mod) dt_mod = _dt_mod_init();
+   if (dt_mod)
+     {
+        if (dt_mod->obj_hook)
+          {
+             priv->mod_data = dt_mod->obj_hook(obj);
+
+             // update module data
+             if (priv->mod_data)
+               {
+                  priv->mod_data->base = obj;
+                  priv->mod_data->field_limit_get = _field_limit_get;
+                  priv->mod_data->field_format_get = _field_format_get;
+               }
+          }
+
+        if (dt_mod->field_create)
+          {
+             for (idx = 0; idx < EFL_UI_CLOCK_TYPE_COUNT; idx++)
+               {
+                  field = priv->field_list + idx;
+                  field->item_obj = dt_mod->field_create(priv->mod_data, idx);
+               }
+          }
+     }
+
+   priv->freeze_sizing = EINA_TRUE;
+   if (!elm_layout_theme_set(obj, "uiclock", "base",
+                             elm_widget_style_get(obj)))
+     CRI("Failed to set layout!");
+
+   _field_list_init(obj);
+   _reload_format(obj);
+   _ticker(obj);
+
+   elm_widget_can_focus_set(obj, EINA_TRUE);
+
+   priv->freeze_sizing = EINA_FALSE;
+   elm_layout_sizing_eval(obj);
+
+   // ACCESS
+   if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
+     {
+        Elm_Access_Info *ai;
+
+        priv->access_obj = _elm_access_edje_object_part_object_register
+          (obj, elm_layout_edje_get(obj), "elm.access");
+        if (!priv->access_obj)
+          priv->access_obj = _elm_access_edje_object_part_object_register
+          (obj, elm_layout_edje_get(obj), "access");
+
+        ai = _elm_access_info_get(priv->access_obj);
+        _elm_access_text_set(ai, ELM_ACCESS_TYPE, "date time");
+        _elm_access_callback_set(ai, ELM_ACCESS_INFO, _access_info_cb, obj);
+     }
+}
+
+EOLIAN static void
+_efl_ui_clock_efl_canvas_group_group_del(Eo *obj, Efl_Ui_Clock_Data *sd)
+{
+   Clock_Field *tmp;
+   unsigned int idx;
+
+   ecore_timer_del(sd->ticker);
+   for (idx = 0; idx < EFL_UI_CLOCK_TYPE_COUNT; idx++)
+     {
+        tmp = sd->field_list + idx;
+        evas_object_del(tmp->item_obj);
+        eina_stringshare_del(tmp->separator);
+     }
+
+   if ((dt_mod) && (dt_mod->obj_unhook))
+     dt_mod->obj_unhook(sd->mod_data);  // module - unhook
+
+   efl_canvas_group_del(efl_super(obj, MY_CLASS));
+}
+
+EOLIAN static Eo *
+_efl_ui_clock_efl_object_constructor(Eo *obj, Efl_Ui_Clock_Data *_pd 
EINA_UNUSED)
+{
+   obj = efl_constructor(efl_super(obj, MY_CLASS));
+   efl_canvas_object_type_set(obj, MY_CLASS_NAME_LEGACY);
+   evas_object_smart_callbacks_descriptions_set(obj, _smart_callbacks);
+   elm_interface_atspi_accessible_role_set(obj, ELM_ATSPI_ROLE_DATE_EDITOR);
+
+   return obj;
+}
+
+EOLIAN static const char*
+_efl_ui_clock_format_get(Eo *obj EINA_UNUSED, Efl_Ui_Clock_Data *sd)
+{
+   return sd->format;
+}
+
+EOLIAN static void
+_efl_ui_clock_format_set(Eo *obj, Efl_Ui_Clock_Data *sd, const char *fmt)
+{
+   if (fmt)
+     {
+        strncpy(sd->format, fmt, EFL_UI_CLOCK_MAX_FORMAT_LEN);
+        sd->format[EFL_UI_CLOCK_MAX_FORMAT_LEN - 1] = '\0';
+        sd->user_format = EINA_TRUE;
+     }
+   else sd->user_format = EINA_FALSE;
+
+   _reload_format(obj);
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_clock_field_visible_get(Eo *obj EINA_UNUSED, Efl_Ui_Clock_Data *sd, 
Efl_Ui_Clock_Type fieldtype)
+{
+   Clock_Field *field;
+
+   if (fieldtype > EFL_UI_CLOCK_TYPE_DAY) return EINA_FALSE;
+
+   field = sd->field_list + fieldtype;
+
+   return field->visible;
+}
+
+EOLIAN static void
+_efl_ui_clock_field_visible_set(Eo *obj, Efl_Ui_Clock_Data *sd, 
Efl_Ui_Clock_Type fieldtype, Eina_Bool visible)
+{
+   char buf[BUFFER_SIZE];
+   Clock_Field *field;
+
+   if (fieldtype > EFL_UI_CLOCK_TYPE_DAY) return;
+
+   field = sd->field_list + fieldtype;
+   visible = !!visible;
+   if (field->visible == visible) return;
+
+   field->visible = visible;
+
+   sd->freeze_sizing = EINA_TRUE;
+   if (visible)
+     {
+        sd->enabled_field_count++;
+
+        if (!field->fmt_exist) return;
+
+        snprintf(buf, sizeof(buf), EDC_PART_FIELD_ENABLE_SIG_STR,
+                 field->location);
+        elm_layout_signal_emit(obj, buf, "elm");
+
+        ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
+        edje_object_message_signal_process(wd->resize_obj);
+
+        snprintf(buf, sizeof(buf), EDC_PART_FIELD_STR, field->location);
+        elm_layout_content_unset(obj, buf);
+        elm_layout_content_set(obj, buf, field->item_obj);
+     }
+   else
+     {
+        sd->enabled_field_count--;
+
+        if (!field->fmt_exist) return;
+
+        snprintf(buf, sizeof(buf), EDC_PART_FIELD_DISABLE_SIG_STR,
+                 field->location);
+        elm_layout_signal_emit(obj, buf, "elm");
+
+        ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
+        edje_object_message_signal_process(wd->resize_obj);
+
+        snprintf(buf, sizeof(buf), EDC_PART_FIELD_STR, field->location);
+        evas_object_hide(elm_layout_content_unset(obj, buf));
+     }
+   sd->freeze_sizing = EINA_FALSE;
+
+   elm_layout_sizing_eval(obj);
+
+   if (!visible) return;
+   if (!dt_mod || !dt_mod->field_value_display) return;
+
+   dt_mod->field_value_display(sd->mod_data, field->item_obj);
+}
+
+EOLIAN static void
+_efl_ui_clock_field_limit_get(Eo *obj EINA_UNUSED, Efl_Ui_Clock_Data *sd, 
Efl_Ui_Clock_Type fieldtype, int *min, int *max)
+{
+   Clock_Field *field;
+
+   if (fieldtype >= EFL_UI_CLOCK_TYPE_DAY) return;
+
+   field = sd->field_list + fieldtype;
+   if (min) *min = field->min;
+   if (max) *max = field->max;
+}
+
+EOLIAN static void
+_efl_ui_clock_field_limit_set(Eo *obj, Efl_Ui_Clock_Data *sd, 
Efl_Ui_Clock_Type fieldtype, int min, int max)
+{
+   Clock_Field *field;
+   struct tm old_time;
+
+   if (fieldtype >= EFL_UI_CLOCK_TYPE_DAY) return;
+
+   if (min > max) return;
+
+   old_time = sd->curr_time;
+   field = sd->field_list + fieldtype;
+   if (((min >= mapping[fieldtype].def_min) &&
+        (min <= mapping[fieldtype].def_max)) ||
+       (field->type == EFL_UI_CLOCK_TYPE_YEAR))
+     field->min = min;
+   if (((max >= mapping[fieldtype].def_min) &&
+        (max <= mapping[fieldtype].def_max)) ||
+       (field->type == EFL_UI_CLOCK_TYPE_YEAR))
+     field->max = max;
+
+   _apply_field_limits(obj);
+
+   if (!_field_cmp(fieldtype, &old_time, &sd->curr_time))
+     efl_event_callback_legacy_call(obj, EFL_UI_CLOCK_EVENT_CHANGED, NULL);
+
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_clock_value_get(Eo *obj EINA_UNUSED, Efl_Ui_Clock_Data *sd, struct tm 
*currtime)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(currtime, EINA_FALSE);
+
+   *currtime = sd->curr_time;
+   return EINA_TRUE;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_clock_value_set(Eo *obj, Efl_Ui_Clock_Data *sd, struct tm *newtime)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(newtime, EINA_FALSE);
+
+   if (_date_cmp(&sd->curr_time, newtime)) return EINA_TRUE;
+   sd->curr_time = *newtime;
+   // apply default field restrictions for curr_time
+   _apply_range_restrictions(&sd->curr_time);
+   // validate the curr_time according to the min_limt and max_limt
+   _validate_clock_limits(&sd->curr_time, &sd->min_limit, EINA_FALSE);
+   _validate_clock_limits(&sd->max_limit, &sd->curr_time, EINA_TRUE);
+   _apply_field_limits(obj);
+
+   efl_event_callback_legacy_call(obj, EFL_UI_CLOCK_EVENT_CHANGED, NULL);
+
+   return EINA_TRUE;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_clock_value_min_get(Eo *obj EINA_UNUSED, Efl_Ui_Clock_Data *sd, 
Efl_Time *mintime)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(mintime, EINA_FALSE);
+
+   *mintime = sd->min_limit;
+   return EINA_TRUE;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_clock_value_min_set(Eo *obj, Efl_Ui_Clock_Data *sd, Efl_Time *mintime)
+{
+   struct tm old_time;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(mintime, EINA_FALSE);
+
+   if (_date_cmp(&sd->min_limit, mintime)) return EINA_TRUE;
+   sd->min_limit = *mintime;
+   old_time = sd->curr_time;
+   // apply default field restrictions for min_limit
+   _apply_range_restrictions(&sd->min_limit);
+   // validate curr_time and max_limt according to the min_limit
+   _validate_clock_limits(&sd->max_limit, &sd->min_limit, EINA_FALSE);
+   _validate_clock_limits(&sd->curr_time, &sd->min_limit, EINA_FALSE);
+   _apply_field_limits(obj);
+
+   if (!_date_cmp(&old_time, &sd->curr_time))
+     efl_event_callback_legacy_call(obj, EFL_UI_CLOCK_EVENT_CHANGED, NULL);
+
+   return EINA_TRUE;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_clock_value_max_get(Eo *obj EINA_UNUSED, Efl_Ui_Clock_Data *sd, struct 
tm *maxtime)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(maxtime, EINA_FALSE);
+
+   *maxtime = sd->max_limit;
+   return EINA_TRUE;
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_clock_value_max_set(Eo *obj, Efl_Ui_Clock_Data *sd, struct tm *maxtime)
+{
+   struct tm old_time;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(maxtime, EINA_FALSE);
+
+   if (_date_cmp(&sd->max_limit, maxtime)) return EINA_TRUE;
+   sd->max_limit = *maxtime;
+   old_time = sd->curr_time;
+   // apply default field restrictions for max_limit
+   _apply_range_restrictions(&sd->max_limit);
+   // validate curr_time and min_limt according to the max_limit
+   _validate_clock_limits(&sd->max_limit, &sd->min_limit, EINA_TRUE);
+   _validate_clock_limits(&sd->max_limit, &sd->curr_time, EINA_TRUE);
+   _apply_field_limits(obj);
+
+   if (!_date_cmp(&old_time, &sd->curr_time))
+     efl_event_callback_legacy_call(obj, EFL_UI_CLOCK_EVENT_CHANGED, NULL);
+
+   return EINA_TRUE;
+}
+
+EOLIAN static void
+_efl_ui_clock_class_constructor(Efl_Class *klass)
+{
+   evas_smart_legacy_type_register(MY_CLASS_NAME_LEGACY, klass);
+}
+
+#include "efl_ui_clock.eo.c"
diff --git a/src/lib/elementary/efl_ui_clock.eo 
b/src/lib/elementary/efl_ui_clock.eo
new file mode 100644
index 0000000..1261cec
--- /dev/null
+++ b/src/lib/elementary/efl_ui_clock.eo
@@ -0,0 +1,260 @@
+import efl_types;
+
+enum Efl.Ui.Clock.Type
+{
+   [[Identifies a clock field, The widget supports 6 fields : Year, month,
+     Date, Hour, Minute, AM/PM
+   ]]
+
+   year    = 0, [[Indicates Year field.]]
+   month   = 1, [[Indicates Month field.]]
+   date    = 2, [[Indicates Date field.]]
+   hour    = 3, [[Indicates Hour field.]]
+   minute  = 4, [[Indicates Minute field.]]
+   second  = 5, [[Indicates Second field.]]
+   day     = 6, [[Indicated Day field.]]
+   ampm    = 7, [[Indicates AM/PM field .]]
+}
+
+class Efl.Ui.Clock (Elm.Layout)
+{
+   methods {
+      @property format {
+         [[The current clock format.
+           Format is a combination of allowed
+           Libc date format specifiers like: "%b %d, %Y %I : %M %p".
+
+           Maximum allowed format length is 64 chars.
+
+           Format can include separators for each individual clock
+           field except for AM/PM field.
+
+           Each separator can be a maximum of 6 UTF-8 bytes.
+           Space is also taken as a separator.
+
+           These specifiers can be arranged in any order and the widget
+           will display the fields accordingly.
+
+           Default format is taken as per the system locale settings.
+         ]]
+         /* FIXME-doc
+         Following are the allowed set of format specifiers for each clock 
field.
+
+         @b %%Y : The year as a decimal number including the century.
+
+         @b %%y : The year as a decimal number without a century (range 00 to 
99).
+
+         @b %%m : The month as a decimal number (range 01 to 12).
+
+         @b %%b : The abbreviated month name according to the current locale.
+
+         @b %%B : The full month name according to the current locale.
+
+         @b %%h : The abbreviated month name according to the current 
locale(same as %%b).
+
+         @b %%d : The day of the month as a decimal number (range 01 to 31).
+
+         @b %%e : The day of the month as a decimal number (range 1 to 31). 
single
+         digits are preceded by a blank.
+
+         @b %%I : The hour as a decimal number using a 12-hour clock (range 01 
to 12).
+
+         @b %%H : The hour as a decimal number using a 24-hour clock (range 00 
to 23).
+
+         @b %%k : The hour (24-hour clock) as a decimal number (range 0 to 
23). single
+         digits are preceded by a blank.
+
+         @b %%l : The hour (12-hour clock) as a decimal number (range 1 to 
12); single
+         digits are preceded by a blank.
+
+         @b %%M : The minute as a decimal number (range 00 to 59).
+
+         @b %%p : Either 'AM' or 'PM' according to the given time value, or the
+         corresponding strings for the current locale. Noon is treated as 'PM'
+         and midnight as 'AM'.
+
+         @b %%P : Like %p but in lower case: 'am' or 'pm' or a corresponding 
string for
+         the current locale.
+
+         @b %%c : The preferred date and time representation for the current 
locale.
+
+         @b %%x : The preferred date representation for the current locale 
without the time.
+
+         @b %%X : The preferred time representation for the current locale 
without the date.
+
+         @b %%r : The complete calendar time using the AM/PM format of the 
current locale.
+
+         @b %%R : The hour and minute in decimal numbers using the format 
%H:%M.
+
+         @b %%T : The time of day in decimal numbers using the format %H:%M:%S.
+
+         @b %%D : The date using the format %%m/%%d/%%y.
+
+         @b %%F : The date using the format %%Y-%%m-%%d.
+         */
+         set {} get {}
+         values {
+            fmt: const(char)* @nullable; [[The clock format.]]
+         }
+      }
+      @property pause {
+         [[Whether the given clock widget should be paused or not.
+
+           This function pauses or starts the clock widget.
+         ]]
+         set {} get {}
+         values {
+            paused: bool; [[$true to pause clock, $false otherwise]]
+         }
+      }
+      @property edit_mode {
+         [[Digits of the given clock widget should be editable when in editing 
mode.]]
+         set {} get {}
+         values {
+            value: bool; [[$true to set edit mode, $false otherwise]]
+         }
+      }
+      @property value_min {
+         [[The lower boundary of a field.
+
+           Year: years since 1900. Negative value represents year below 1900
+           (year value -30 represents 1870). Year default range is from 70
+           to 137.
+
+           Month: default value range is from 0 to 11.
+
+           Date: default value range is from 1 to 31 according to the month
+           value.
+
+           Hour: default value will be in terms of 24 hr format (0~23)
+
+           Minute: default value range is from 0 to 59.
+         ]]
+         set {
+            return: bool;
+         }
+         get {
+            return: bool;
+         }
+
+         keys {
+            mintime: Efl.Time*; [[Time structure containing the minimum time 
value.]]
+         }
+      }
+      @property value_max {
+         [[The upper boundary of a field.
+
+           Year: years since 1900. Negative value represents year below 1900
+           (year value -30 represents 1870). Year default range is from 70
+           to 137.
+
+           Month: default value range is from 0 to 11.
+
+           Date: default value range is from 1 to 31 according to the month
+           value.
+
+           Hour: default value will be in terms of 24 hr format (0~23)
+
+           Minute: default value range is from 0 to 59.
+         ]]
+         set {
+            return: bool;
+         }
+         get {
+            return: bool;
+         }
+
+         keys {
+            maxtime: Efl.Time*; [[Time structure containing the minimum time 
value.]]
+         }
+      }
+      @property value {
+         [[The current value of a clock object.
+
+           Year: years since 1900. Negative value represents year below 1900
+           (year value -30 represents 1870). Year default range is from 70
+           to 137.
+
+           Month: default value range is from 0 to 11.
+
+           Date: default value range is from 1 to 31 according to the month
+           value.
+
+           Hour: default value will be in terms of 24 hr format (0~23)
+
+           Minute: default value range is from 0 to 59.
+         ]]
+         set {
+            return: bool;
+         }
+         get {
+            return: bool;
+         }
+         keys {
+            curtime: Efl.Time*; [[Time structure containing the minimum time 
value.]]
+         }
+      }
+      @property field_visible {
+         [[ The field to be visible/not.]]
+         set{} get{}
+         keys {
+            fieldtype: Efl.Ui.Clock.Type; [[Type of the field. 
#EFL_UI_CLOCK_TYPE_YEAR etc.]]
+         }
+         values {
+            visible: bool; [[$true field can be visible, $false otherwise.]]
+         }
+      }
+      @property field_limit {
+         set {
+             [[Set a field to be visible or not.
+
+              Setting this API to $true does not ensure that the field is
+              visible, apart from this, the field's format must be present
+              in clock overall format.  If a field's visibility is set
+              to $false then it won't appear even though its format is
+              present in overall format. So if and only if this API is
+              set true and the corresponding field's format is present
+              in clock format, the field is visible.
+
+              By default the field visibility is set to $true.
+            ]]
+         }
+         get {
+            [[ Get the field limits of a field.
+
+              Limits can be set to individual fields, independently, except
+              for AM/PM field. Any field can display the values only in between
+              these minimum and maximum limits unless the corresponding time
+              value is restricted from MinTime to MaxTime. That is, min/max
+              field limits always works under the limitations of 
mintime/maxtime.
+
+              There is no provision to set the limits of AM/PM field.
+            ]]
+         }
+         keys {
+            fieldtype: Efl.Ui.Clock.Type; [[Type of the field. 
#EFL_UI_CLOCK_TYPE_YEAR etc.]]
+         }
+         values {
+            min: int; [[Reference to field's minimum value.]]
+            max: int; [[Reference to field's maximum value.]]
+         }
+      }
+   }
+   implements {
+      class.constructor;
+      Efl.Object.constructor;
+      Efl.Canvas.Group.group_add;
+      Efl.Canvas.Group.group_del;
+      Elm.Widget.theme_apply;
+      Elm.Widget.focus_next_manager_is;
+      Elm.Widget.focus_next;
+      Elm.Widget.disable;
+      Elm.Widget.on_focus;
+      Elm.Widget.translate;
+      Elm.Layout.sizing_eval;
+   }
+   events {
+      changed;
+   }
+
+}
diff --git a/src/lib/elementary/efl_ui_clock.h 
b/src/lib/elementary/efl_ui_clock.h
new file mode 100644
index 0000000..4607d39
--- /dev/null
+++ b/src/lib/elementary/efl_ui_clock.h
@@ -0,0 +1,204 @@
+/**
+ * @defgroup efl_ui_clock
+ * @ingroup Elementary
+ *
+ * @image html clock_inheritance_tree.png
+ * @image latex clock_inheritance_tree.eps
+ *
+ * @image html img/widget/clock/preview-00.png
+ * @image latex img/widget/clock/preview-00.eps
+ *
+ * @image html img/widget/clock/preview-01.png
+ * @image latex img/widget/clock/preview-01.eps
+ *
+ * @image html img/widget/clock/preview-02.png
+ * @image latex img/widget/clock/preview-02.eps
+ *
+ * Clock widget is used to display and input date & time values.
+ * This widget displays date and time as per the <b>system's locale</b> 
settings (Date
+ * includes Day, Month & Year along with the defined separators and
+ * Time includes Hour, Minute & AM/PM fields. Separator for AM/PM field is 
ignored.
+ *
+ * The corresponding Month, AM/PM strings are displayed according to the
+ * system’s language settings.
+ *
+ * Clock format is a combination of LIBC standard characters like
+ * “%%d %%b %%Y %%I : %%M  %%p” which, as a whole represents both Date as well 
as Time
+ * format.
+ *
+ * efl_ui_clock supports only the following sub set of libc date format 
specifiers:
+ *
+ * @b %%Y : The year as a decimal number including the century (example: 2011).
+ *
+ * @b %%y : The year as a decimal number without a century (range 00 to 99)
+ *
+ * @b %%m : The month as a decimal number (range 01 to 12).
+ *
+ * @b %%b : The abbreviated month name according to the current locale.
+ *
+ * @b %%B : The full month name according to the current locale.
+ *
+ * @b %%h : The abbreviated month name according to the current locale(same as 
%%b).
+ *
+ * @b %%d : The day of the month as a decimal number (range 01 to 31).
+ *
+ * @b %%e : The day of the month as a decimal number (range 1 to 31). single
+ * digits are preceded by a blank.
+ *
+ * @b %%I : The hour as a decimal number using a 12-hour clock (range 01 to 
12).
+ *
+ * @b %%H : The hour as a decimal number using a 24-hour clock (range 00 to 
23).
+ *
+ * @b %%k : The hour (24-hour clock) as a decimal number (range 0 to 23). 
single
+ * digits are preceded by a blank.
+ *
+ * @b %%l : The hour (12-hour clock) as a decimal number (range 1 to 12); 
single
+ * digits are preceded by a blank.
+ *
+ * @b %%M : The minute as a decimal number (range 00 to 59).
+ *
+ * @b %%p : Either 'AM' or 'PM' according to the given time value, or the
+ * corresponding strings for the current locale. Noon is treated as 'PM'
+ * and midnight as 'AM'
+ *
+ * @b %%P : Like %p but in lower case: 'am' or 'pm' or a corresponding string 
for
+ * the current locale.
+ *
+ * @b %%c : The preferred date and time representation for the current locale.
+ *
+ * @b %%x : The preferred date representation for the current locale without 
the time.
+ *
+ * @b %%X : The preferred time representation for the current locale without 
the date.
+ *
+ * @b %%r : The complete calendar time using the AM/PM format of the current 
locale.
+ *
+ * @b %%R : The hour and minute in decimal numbers using the format %H:%M.
+ *
+ * @b %%T : The time of day in decimal numbers using the format %H:%M:%S.
+ *
+ * @b %%D : The date using the format %%m/%%d/%%y.
+ *
+ * @b %%F : The date using the format %%Y-%%m-%%d.
+ *
+ * (For more reference on the available <b>LIBC date format specifiers</b>, 
please
+ * visit the link:
+ * http://www.gnu.org/s/hello/manual/libc.html#Formatting-Calendar-Time )
+ *
+ * Clock widget can provide Unicode @b separators in between its fields
+ * except for AM/PM field.
+ * A separator can be any <b>Unicode character</b> other than the LIBC standard
+ * date format specifiers.( Example: In the format %%b %%d @b , %%y %%H @b : 
%%M
+ * comma(,) is separator for date field %%d and colon(:) is separator for
+ * hour field %%H ).
+ *
+ * The default format is a predefined one, based on the system Locale.
+ *
+ * Hour format 12hr(1-12) or 24hr(0-23) display can be selected by setting
+ * the corresponding user format.
+ *
+ * Clock supports six fields: Year, Month, Date, Hour, Minute, AM/PM.
+ * Depending on the Clock module that is loaded, the user can see
+ * different UI to select the individual field values.
+ *
+ * The individual fields of Clock can be arranged in any order according to 
the format
+ * set by application.
+ *
+ * There is a provision to set the visibility of a particular field as TRUE/ 
FALSE
+ * so that <b>only time/ only date / only required fields</b> will be 
displayed.
+ *
+ * Each field is having a default minimum and maximum values just like the 
daily
+ * calendar information. These min/max values can be modified as per the 
application usage.
+ *
+ * User can enter the values only in between the range of maximum and minimum.
+ * Apart from these APIs, there is a provision to display only a limited set of
+ * values out of the possible values. APIs to select the individual field 
limits
+ * are intended for this purpose.
+ *
+ * The whole widget is left aligned and its size grows horizontally depending
+ * on the current format and each field's visible/disabled state.
+ *
+ * Clock individual field selection is implemented in a modular style.
+ * Module can be implemented as a Ctxpopup based selection or an ISE based
+ * selection or even a spinner like selection etc.
+ *
+ * <b>Clock Module design:</b>
+ *
+ * The following functions are expected to be implemented in a Clock module:
+ *
+ * <b>Field creation:</b>
+ * <pre>
+ *
+ *  __________                                            __________
+ * |          |----- obj_hook() ---------------------->>>|          |
+ * |          |<<<----------------returns Mod_data ------|          |
+ * |  Clock   |_______                                   |          |
+ * |  widget  |       |Assign module call backs          |  Module  |
+ * |   base   |<<<____|                                  |          |
+ * |          |                                          |          |
+ * |          |----- field_create() ------------------>>>|          |
+ * |__________|<<<----------------returns field_obj -----|__________|
+ *
+ * </pre>
+ *
+ * <b>Field value setting:</b>
+ * <pre>
+ *
+ *  __________                                          __________
+ * |          |                                        |          |
+ * |  Clock   |<<<----------efl_ui_clock_value_set()---|          |
+ * |  widget  |                                        |  Module  |
+ * |   base   |----display_field_value()------------>>>|          |
+ * |__________|                                        |__________|
+ *
+ * </pre>
+ *
+ * <b>del_hook:</b>
+ * <pre>
+ *  __________                                          __________
+ * |          |                                        |          |
+ * |   Clock  |----obj_unhook()-------------------->>>>|          |
+ * |  widget  |                                        |  Module  |
+ * |   base   |         <<<-----frees mod_data---------|          |
+ * |__________|                                        |__________|
+ *
+ * </pre>
+ *
+ *
+ * Any module can use the following shared functions that are implemented in 
efl_ui_clock.c :
+ *
+ * <b>field_format_get()</b> - gives the field format.
+ *
+ * <b>field_limit_get()</b>  - gives the field minimum, maximum limits.
+ *
+ * To enable a module, set the ELM_MODULES environment variable as shown:
+ *
+ * <b>export ELM_MODULES="clock_input_ctxpopup>clock/api"</b>
+ *
+ * This widget inherits from the @ref Layout one, so that all the
+ * functions acting on it also work for Clock objects.
+ *
+ * This widget emits the following signals, besides the ones sent from
+ * @ref Layout:
+ * @li @b "changed" - whenever Clock field value is changed, this
+ * signal is sent.
+ * @li @b "language,changed" - whenever system locale changes, this
+ * signal is sent.
+ * @li @c "focused" - When the Clock has received focus. (since 1.8)
+ * @li @c "unfocused" - When the Clock has lost focus. (since 1.8)
+ *
+ * Here is an example on its usage:
+ * @li @ref clock_example
+ *
+ */
+
+/**
+ * @addtogroup efl_ui_clock
+ * @{
+ */
+
+#ifdef EFL_EO_API_SUPPORT
+#include "efl_ui_clock.eo.h"
+#endif
+/**
+ * @}
+ */
diff --git a/src/lib/elementary/efl_ui_clock_private.h 
b/src/lib/elementary/efl_ui_clock_private.h
new file mode 100644
index 0000000..976fbbd
--- /dev/null
+++ b/src/lib/elementary/efl_ui_clock_private.h
@@ -0,0 +1,130 @@
+#ifndef EFL_UI_CLOCK_PRIVATE_H
+#define EFL_UI_CLOCK_PRIVATE_H
+
+#include "Elementary.h"
+
+/* DO NOT USE THIS HEADER UNLESS YOU ARE PREPARED FOR BREAKING OF YOUR
+ * CODE. THIS IS ELEMENTARY'S INTERNAL WIDGET API (for now) AND IS NOT
+ * FINAL. CALL elm_widget_api_check(ELM_INTERNAL_API_VERSION) TO CHECK
+ * IT AT RUNTIME.
+ */
+
+/**
+ * @addtogroup Widget
+ * @{
+ *
+ * @section efl-ui-clock-class The Elementary Clock Class
+ *
+ * Elementary, besides having the @ref Clock widget, exposes its
+ * foundation -- the Elementary Clock Class -- in order to create other
+ * widgets which are a Clock with some more logic on top.
+ */
+
+/**
+ * Base layout smart data extended with Clock instance data.
+ */
+typedef struct _Efl_Ui_Clock_Module_Data Efl_Ui_Clock_Module_Data;
+typedef struct _Efl_Ui_Clock_Data        Efl_Ui_Clock_Data;
+typedef struct _Clock_Field              Clock_Field;
+typedef struct _Clock_Mod_Api            Clock_Mod_Api;
+typedef struct _Format_Map               Format_Map;
+
+#define EFL_UI_CLOCK_TYPE_COUNT           8
+#define EFL_UI_CLOCK_MAX_FORMAT_LEN       64
+#define EFL_UI_CLOCK_MAX_FIELD_FORMAT_LEN 3
+
+struct _Efl_Ui_Clock_Module_Data
+{
+   Evas_Object *base;
+   void         (*field_limit_get)(Evas_Object *obj,
+                                   Efl_Ui_Clock_Type field_type,
+                                   int *range_min,
+                                   int *range_max);
+   const char  *(*field_format_get)(Evas_Object * obj,
+                                    Efl_Ui_Clock_Type field_type);
+};
+
+struct _Clock_Field
+{
+   Evas_Object            *item_obj;
+   char                    fmt[EFL_UI_CLOCK_MAX_FIELD_FORMAT_LEN];
+   Efl_Ui_Clock_Type type;
+   const char             *separator;
+   int                     location;  /* location of the field as per
+                                       * current format */
+   int                     min, max;
+   Eina_Bool               fmt_exist : 1;  /* whether field format is
+                                            * present or not */
+   Eina_Bool               visible : 1;  /* whether field can be
+                                          * visible or not */
+};
+
+struct _Clock_Mod_Api
+{
+   Efl_Ui_Clock_Module_Data *(*obj_hook)(Evas_Object * obj);
+   void                      (*obj_unhook)(Efl_Ui_Clock_Module_Data *mdata);
+   void                      (*obj_hide)(Efl_Ui_Clock_Module_Data *mdata);
+   Evas_Object              *(*field_create)(Efl_Ui_Clock_Module_Data * mdata,
+                                             Efl_Ui_Clock_Type ftype);
+   void                      (*field_value_display)(Efl_Ui_Clock_Module_Data
+                                                    *mdata,
+                                                    Evas_Object *obj);
+};
+
+struct _Efl_Ui_Clock_Data
+{
+   /* fixed set of fields. */
+   Clock_Field            field_list[EFL_UI_CLOCK_TYPE_COUNT];
+   struct tm                 curr_time, min_limit, max_limit;
+   Efl_Ui_Clock_Module_Data *mod_data;
+   char                      format[EFL_UI_CLOCK_MAX_FORMAT_LEN];
+   Evas_Object              *access_obj;
+   int                       enabled_field_count;
+   Ecore_Timer              *ticker;
+   Eina_Bool                 paused : 1;
+   Eina_Bool                 edit_mode : 1;
+   Eina_Bool                 user_format : 1;  /* whether user set
+                                                * format or default
+                                                * format. */
+   Eina_Bool                 freeze_sizing : 1; /* freeze sizing_eval to
+                                                 * reduce unnecessary sizing */
+};
+
+struct _Format_Map
+{
+   char *fmt_char;
+   int   def_min;
+   int   def_max;
+   char *ignore_sep;
+};
+
+/**
+ * @}
+ */
+
+#define EFL_UI_CLOCK_DATA_GET(o, sd) \
+  Efl_Ui_Clock_Data * sd = efl_data_scope_get(o, EFL_UI_CLOCK_CLASS)
+
+#define EFL_UI_CLOCK_DATA_GET_OR_RETURN(o, ptr)      \
+  EFL_UI_CLOCK_DATA_GET(o, ptr);                     \
+  if (EINA_UNLIKELY(!ptr))                           \
+    {                                                \
+       CRI("No widget data for object %p (%s)",      \
+           o, evas_object_type_get(o));              \
+       return;                                       \
+    }
+
+#define EFL_UI_CLOCK_DATA_GET_OR_RETURN_VAL(o, ptr, val) \
+  EFL_UI_CLOCK_DATA_GET(o, ptr);                         \
+  if (EINA_UNLIKELY(!ptr))                               \
+    {                                                    \
+       CRI("No widget data for object %p (%s)",          \
+           o, evas_object_type_get(o));                  \
+       return val;                                       \
+    }
+
+#define EFL_UI_CLOCK_CHECK(obj)                              \
+  if (EINA_UNLIKELY(!eo_isa((obj), EFL_UI_CLOCK_CLASS))) \
+    return
+
+#endif
diff --git a/src/lib/elementary/elm_config.c b/src/lib/elementary/elm_config.c
index 4661611..513a154 100644
--- a/src/lib/elementary/elm_config.c
+++ b/src/lib/elementary/elm_config.c
@@ -2194,6 +2194,10 @@ _config_update(void)
    IFCFG(0x000a)
    _elm_config->icon_theme = 
eina_stringshare_add(ELM_CONFIG_ICON_THEME_ELEMENTARY);
    IFCFGEND
+
+   IFCFG(0x000b)
+   eina_stringshare_refplace(&_elm_config->modules, tcfg->modules);
+   IFCFGEND
    /**
     * Fix user config for current ELM_CONFIG_EPOCH here.
     **/

-- 


Reply via email to