[datetime_input_popup] elm_datetime new module is added: dark theme UX v0.7 implemented.
authorsumanth <sumanth.m@samsung.com>
Wed, 19 Jun 2013 21:35:19 +0000 (03:05 +0530)
committerSungho Kwak <sungho1.kwak@samsung.com>
Thu, 4 Jul 2013 07:37:42 +0000 (16:37 +0900)
Change-Id: Id776177a711bc60af9fdea15b4492cd4e0292f9e

Conflicts:

config/mobile/base.src

config/default/base.src
config/illume/base.src
config/mobile/base.src
configure.ac
src/lib/elm_datetime.c
src/modules/Makefile.am
src/modules/datetime_input_popup/Makefile.am [new file with mode: 0644]
src/modules/datetime_input_popup/datetime_input_popup.c [new file with mode: 0644]

index 31a50cd..27fc45c 100644 (file)
@@ -34,7 +34,7 @@ group "Elm_Config" struct {
   value "finger_size" int: 40;
   value "fps" double: 60.0;
   value "theme" string: "default";
-  value "modules" string: "access_output>access/api:datetime_input_ctxpopup>datetime/api";
+  value "modules" string: "access_output>access/api:datetime_input_popup>datetime/api";
   value "tooltip_delay" double: 1.0;
   value "cursor_engine_only" uchar: 1;
   value "focus_highlight_enable" uchar: 0;
index cd51eab..24da4b1 100644 (file)
@@ -33,7 +33,7 @@ group "Elm_Config" struct {
   value "finger_size" int: 40;
   value "fps" double: 60.0;
   value "theme" string: "default";
-  value "modules" string: "datetime_input_ctxpopup>datetime/api";
+  value "modules" string: "datetime_input_popup>datetime/api";
   value "tooltip_delay" double: 1.0;
   value "cursor_engine_only" uchar: 1;
   value "focus_highlight_enable" uchar: 0;
index 4280f79..d991a87 100644 (file)
@@ -34,7 +34,7 @@ group "Elm_Config" struct {
   value "finger_size" int: 60;
   value "fps" double: 60.0;
   value "theme" string: "tizen-hd";
-  value "modules" string: "ctxpopup_copypasteUI>entry/api:datetime_input_ctxpopup>datetime/api:access_output_tts>access/api";
+  value "modules" string: "ctxpopup_copypasteUI>entry/api:datetime_input_popup>datetime/api:access_output_tts>access/api";
   value "tooltip_delay" double: 1.0;
   value "cursor_engine_only" uchar: 1;
   value "focus_highlight_enable" uchar: 0;
index 9c1b591..3ecfa02 100644 (file)
@@ -776,6 +776,7 @@ src/bin/Makefile
 src/modules/Makefile
 src/modules/access_output/Makefile
 src/modules/datetime_input_ctxpopup/Makefile
+src/modules/datetime_input_popup/Makefile
 src/modules/test_entry/Makefile
 src/modules/test_map/Makefile
 src/modules/test_map_engine/Makefile
index 2da5d1c..a66558c 100644 (file)
@@ -28,6 +28,8 @@ EAPI const char ELM_DATETIME_SMART_NAME[] = "elm_datetime";
 #define EDC_PART_FIELD_DISABLE_SIG_STR "field%d,disable"
 #define EDC_PART_FIELD_SEPARATOR_ENABLE_SIG_STR  "field%d,separator,enable"
 #define EDC_PART_FIELD_SEPARATOR_DISABLE_SIG_STR "field%d,separator,disable"
+#define EDC_PART_TIMEPICKER_STARTING_FIELD_STR "timepicker,starting,field%d"
+#define EDC_PART_DATEPICKER_STARTING_FIELD_STR "datepicker,starting,field%d"
 
 /* struct tm does not define the fields in the order year, month,
  * date, hour, minute. values are reassigned to an array for easy
@@ -213,6 +215,8 @@ _field_list_arrange(Evas_Object *obj)
    Datetime_Field *field;
    char buf[BUFFER_SIZE];
    int idx;
+   int datepicker_start_idx = ELM_DATETIME_TYPE_COUNT;
+   int timepicker_start_idx = ELM_DATETIME_TYPE_COUNT;
 
    ELM_DATETIME_DATA_GET(obj, sd);
 
@@ -231,6 +235,27 @@ _field_list_arrange(Evas_Object *obj)
           elm_layout_content_set(obj, buf, field->item_obj);
      }
 
+   for (idx = 0; idx < ELM_DATETIME_HOUR; idx++)
+     {
+        field = sd->field_list + idx;
+        if ((field->fmt_exist) && (field->location < datepicker_start_idx))
+          datepicker_start_idx = field->location;
+     }
+
+   snprintf(buf, sizeof(buf), EDC_PART_DATEPICKER_STARTING_FIELD_STR,
+            datepicker_start_idx);
+   elm_layout_signal_emit(obj, buf, "elm");
+
+   for (idx = ELM_DATETIME_HOUR; idx < ELM_DATETIME_TYPE_COUNT; idx++)
+     {
+        field = sd->field_list + idx;
+        if ((field->fmt_exist) && (field->location < timepicker_start_idx))
+          timepicker_start_idx = field->location;
+     }
+   snprintf(buf, sizeof(buf), EDC_PART_TIMEPICKER_STARTING_FIELD_STR,
+            timepicker_start_idx);
+   elm_layout_signal_emit(obj, buf, "elm");
+
    elm_layout_sizing_eval(obj);
    _field_list_display(obj);
 }
@@ -385,8 +410,8 @@ _reload_format(Evas_Object *obj)
           }
      }
 
-   edje_object_message_signal_process(ELM_WIDGET_DATA(sd)->resize_obj);
    _field_list_arrange(obj);
+   edje_object_message_signal_process(ELM_WIDGET_DATA(sd)->resize_obj);
 }
 
 static Eina_Bool
index 73edf2e..30806e8 100644 (file)
@@ -6,5 +6,6 @@ test_entry \
 test_map \
 test_map_engine \
 access_output \
+datetime_input_popup \
 datetime_input_ctxpopup \
 ctxpopup_copypasteUI
diff --git a/src/modules/datetime_input_popup/Makefile.am b/src/modules/datetime_input_popup/Makefile.am
new file mode 100644 (file)
index 0000000..2536f5b
--- /dev/null
@@ -0,0 +1,43 @@
+
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CPPFLAGS = \
+-DELM_INTERNAL_API_ARGESFSDFEFC=1 \
+-I. \
+-I$(top_builddir) \
+-I$(top_srcdir) \
+-I$(top_srcdir)/src/lib \
+-I$(top_builddir)/src/lib \
+-DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \
+-DPACKAGE_LIB_DIR=\"$(libdir)\" \
+@ELEMENTARY_CFLAGS@ \
+@ELEMENTARY_X_CFLAGS@ \
+@ELEMENTARY_FB_CFLAGS@ \
+@ELEMENTARY_SDL_CFLAGS@ \
+@ELEMENTARY_WIN32_CFLAGS@ \
+@ELEMENTARY_WINCE_CFLAGS@ \
+@ELEMENTARY_EDBUS_CFLAGS@ \
+@ELEMENTARY_EFREET_CFLAGS@ \
+@ELEMENTARY_EWEATHER_CFLAGS@ \
+@ELEMENTARY_ETHUMB_CFLAGS@ \
+@ELEMENTARY_WEB_CFLAGS@ \
+@ELEMENTARY_EMAP_CFLAGS@ \
+@ELEMENTARY_ECORE_CON_CFLAGS@ \
+@ELEMENTARY_ECORE_IMF_CFLAGS@ \
+@ELEMENTARY_WAYLAND_CFLAGS@ \
+@EVIL_CFLAGS@ \
+@EIO_CFLAGS@ \
+@EMOTION_CFLAGS@
+
+if ELEMENTARY_WINDOWS_BUILD
+AM_CPPFLAGS += -DELEMENTARY_BUILD
+endif
+
+pkgdir = $(libdir)/elementary/modules/datetime_input_popup/$(MODULE_ARCH)
+pkg_LTLIBRARIES = module.la
+
+module_la_SOURCES = datetime_input_popup.c
+
+module_la_LIBADD = @ELEMENTARY_LIBS@ $(top_builddir)/src/lib/libelementary.la
+module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
+module_la_LIBTOOLFLAGS = --tag=disable-static
diff --git a/src/modules/datetime_input_popup/datetime_input_popup.c b/src/modules/datetime_input_popup/datetime_input_popup.c
new file mode 100644 (file)
index 0000000..b450461
--- /dev/null
@@ -0,0 +1,838 @@
+#include <Elementary.h>
+#include "elm_priv.h"
+
+#define DATETIME_FIELD_COUNT            6
+#define BUFF_SIZE                       1024
+#define MONTH_STRING_MAX_SIZE           32
+#define TOTAL_NUMBER_OF_MONTHS          12
+#define STRUCT_TM_YEAR_BASE_VALUE       1900
+#define STRUCT_TM_TIME_12HRS_MAX_VALUE  12
+
+static const char *field_styles[] = {
+                         "year", "month", "date", "hour", "minute", "ampm" };
+
+static int days_in_month[TOTAL_NUMBER_OF_MONTHS] = {
+                         31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+
+static char month_arr[TOTAL_NUMBER_OF_MONTHS][MONTH_STRING_MAX_SIZE];
+
+typedef struct _Popup_Module_Data Popup_Module_Data;
+
+struct _Popup_Module_Data
+{
+   Elm_Datetime_Module_Data mod_data;
+   Evas_Object *popup;
+   Evas_Object *date_layout, *time_layout;
+   Evas_Object *sel_field;
+   Evas_Object *popup_field[DATETIME_FIELD_COUNT];
+};
+
+static void
+_set_datetime_value(Popup_Module_Data *popup_mod)
+{
+   struct tm set_time;
+   int is_pm;
+
+   if (!popup_mod) return;
+
+   elm_datetime_value_get(popup_mod->mod_data.base, &set_time);
+
+   set_time.tm_year = (int)elm_spinner_value_get(popup_mod->popup_field[ELM_DATETIME_YEAR]) - STRUCT_TM_YEAR_BASE_VALUE;
+   set_time.tm_mon = (int)elm_spinner_value_get(popup_mod->popup_field[ELM_DATETIME_MONTH]) - 1;
+   set_time.tm_mday = (int)elm_spinner_value_get(popup_mod->popup_field[ELM_DATETIME_DATE]);
+   set_time.tm_hour = (int)elm_spinner_value_get(popup_mod->popup_field[ELM_DATETIME_HOUR]);
+   set_time.tm_min = (int)elm_spinner_value_get(popup_mod->popup_field[ELM_DATETIME_MINUTE]);
+   is_pm = (int)elm_spinner_value_get(popup_mod->popup_field[ELM_DATETIME_AMPM]);
+   if (is_pm) set_time.tm_hour += STRUCT_TM_TIME_12HRS_MAX_VALUE;
+   set_time.tm_hour = (set_time.tm_hour == STRUCT_TM_TIME_12HRS_MAX_VALUE) ? 0 : set_time.tm_hour;
+   set_time.tm_hour = (set_time.tm_hour == 24) ? STRUCT_TM_TIME_12HRS_MAX_VALUE : set_time.tm_hour;
+   //mktime(&set_time);
+   elm_datetime_value_set(popup_mod->mod_data.base, &set_time);
+}
+
+static void
+_popup_set_btn_clicked_cb(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Popup_Module_Data *popup_mod;
+
+   popup_mod = (Popup_Module_Data *)data;
+   if (!popup_mod) return;
+
+   elm_object_signal_emit(popup_mod->sel_field, "elm,state,unselect", "elm");
+   evas_object_hide(popup_mod->popup);
+
+   _set_datetime_value(popup_mod);
+}
+
+static void
+_popup_cancel_btn_clicked_cb(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Popup_Module_Data *popup_mod;
+   popup_mod = (Popup_Module_Data *)data;
+   if (!popup_mod) return;
+
+   elm_object_signal_emit(popup_mod->sel_field, "elm,state,unselect", "elm");
+   evas_object_hide(popup_mod->popup);
+}
+
+static void
+_set_popup_content(Popup_Module_Data *popup_mod)
+{
+   Evas_Object *content;
+   struct tm curr_time;
+   int idx, year, month, min, max;
+   int ampm_min = 0, ampm_max = 1;
+   Elm_Datetime_Field_Type  field_type = ELM_DATETIME_YEAR;
+   Eina_Bool is_pm = EINA_FALSE;
+
+   if (!popup_mod || !popup_mod->mod_data.base) return;
+
+   content = elm_object_content_get(popup_mod->popup);
+   field_type = (Elm_Datetime_Field_Type )evas_object_data_get(popup_mod->sel_field, "_field_type");
+
+   if ((field_type < ELM_DATETIME_HOUR) && (content != popup_mod->date_layout))
+     {
+         elm_object_content_unset(popup_mod->popup);
+         if (content) evas_object_hide(content);
+         elm_object_content_set(popup_mod->popup, popup_mod->date_layout);
+         evas_object_show(popup_mod->date_layout);
+         elm_object_part_text_set(popup_mod->popup, "title,text", "Set date");
+     }
+   if ((field_type >= ELM_DATETIME_HOUR) && (content != popup_mod->time_layout))
+     {
+         elm_object_content_unset(popup_mod->popup);
+         if (content) evas_object_hide(content);
+         elm_object_content_set(popup_mod->popup, popup_mod->time_layout);
+         evas_object_show(popup_mod->time_layout);
+         elm_object_part_text_set(popup_mod->popup, "title,text", "Set time");
+     }
+
+   elm_datetime_value_get(popup_mod->mod_data.base, &curr_time);
+
+   year = curr_time.tm_year + STRUCT_TM_YEAR_BASE_VALUE;
+   elm_spinner_value_set(popup_mod->popup_field[ELM_DATETIME_YEAR], year);
+   month = curr_time.tm_mon + 1;
+   elm_spinner_value_set(popup_mod->popup_field[ELM_DATETIME_MONTH], month);
+   elm_spinner_value_set(popup_mod->popup_field[ELM_DATETIME_DATE], curr_time.tm_mday);
+
+   if (curr_time.tm_hour >= STRUCT_TM_TIME_12HRS_MAX_VALUE)
+     is_pm = EINA_TRUE;
+   if (curr_time.tm_hour >= STRUCT_TM_TIME_12HRS_MAX_VALUE)
+      curr_time.tm_hour -= STRUCT_TM_TIME_12HRS_MAX_VALUE;
+   curr_time.tm_hour = (curr_time.tm_hour == 0) ? STRUCT_TM_TIME_12HRS_MAX_VALUE : curr_time.tm_hour;
+   elm_spinner_value_set(popup_mod->popup_field[ELM_DATETIME_HOUR], curr_time.tm_hour);
+   elm_spinner_value_set(popup_mod->popup_field[ELM_DATETIME_MINUTE], curr_time.tm_min);
+   elm_spinner_value_set(popup_mod->popup_field[ELM_DATETIME_AMPM], is_pm);
+
+   for (idx = 0; idx < DATETIME_FIELD_COUNT -1; idx++)
+     {
+         field_type = (Elm_Datetime_Field_Type)idx;
+         popup_mod->mod_data.field_limit_get(popup_mod->mod_data.base, field_type, &min, &max);
+         if (idx == ELM_DATETIME_YEAR)
+           elm_spinner_min_max_set(popup_mod->popup_field[idx], (STRUCT_TM_YEAR_BASE_VALUE + min), (STRUCT_TM_YEAR_BASE_VALUE + max));
+         else if (idx == ELM_DATETIME_MONTH)
+           elm_spinner_min_max_set(popup_mod->popup_field[idx], (1+min), (1+max));
+         else if (idx == ELM_DATETIME_HOUR)
+           {
+              if (min < 1) min = 1;
+              else if (min > STRUCT_TM_TIME_12HRS_MAX_VALUE)
+               {
+                  min = min - STRUCT_TM_TIME_12HRS_MAX_VALUE;
+                  ampm_min = 1;
+               }
+              if (max > STRUCT_TM_TIME_12HRS_MAX_VALUE) max = STRUCT_TM_TIME_12HRS_MAX_VALUE;
+              else if (max < STRUCT_TM_TIME_12HRS_MAX_VALUE) ampm_max = 0;
+              elm_spinner_min_max_set(popup_mod->popup_field[idx], min, max);
+            }
+         else
+           elm_spinner_min_max_set(popup_mod->popup_field[idx], min, max);
+     }
+   elm_spinner_min_max_set(popup_mod->popup_field[ELM_DATETIME_AMPM], ampm_min, ampm_max);
+}
+
+static void
+_entry_activated_cb(void *data, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   Popup_Module_Data *popup_mod;
+   Evas_Object *entry, *en;
+   int idx;
+
+   popup_mod = (Popup_Module_Data *)data;
+   if (!popup_mod) return;
+
+   elm_object_focus_set(obj, EINA_FALSE);
+   for (idx = 0; idx < ELM_DATETIME_DATE; idx++)
+     {
+        entry = elm_object_part_content_get(popup_mod->popup_field[idx], "elm.swallow.entry");
+        if (obj == entry)
+          {
+             idx++;
+             en = elm_object_part_content_get(popup_mod->popup_field[idx], "elm.swallow.entry");
+             elm_layout_signal_emit(popup_mod->popup_field[idx], "elm,action,entry,toggle", "elm");
+             elm_object_focus_set(en, EINA_TRUE);
+             return;
+          }
+     }
+   entry = elm_object_part_content_get(popup_mod->popup_field[ELM_DATETIME_HOUR], "elm.swallow.entry");
+   if (obj == entry)
+     {
+        en = elm_object_part_content_get(popup_mod->popup_field[ELM_DATETIME_MINUTE], "elm.swallow.entry");
+        elm_layout_signal_emit(popup_mod->popup_field[ELM_DATETIME_MINUTE],
+                               "elm,action,entry,toggle", "elm");
+        elm_object_focus_set(en, EINA_TRUE);
+     }
+}
+
+static void
+_entry_clicked_cb(void *data, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   Popup_Module_Data *popup_mod;
+
+   popup_mod = (Popup_Module_Data *)data;
+   if (!popup_mod || !obj) return;
+
+   elm_entry_cursor_end_set(obj);
+}
+
+static void
+_entry_focused_cb(void *data, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   Popup_Module_Data *popup_mod;
+   Evas_Object *entry;
+   int idx, value;
+
+   popup_mod = (Popup_Module_Data *)data;
+   if (!popup_mod) return;
+
+   for (idx = 0; idx < DATETIME_FIELD_COUNT -1; idx++)
+     {
+        entry = elm_object_part_content_get(popup_mod->popup_field[idx], "elm.swallow.entry");
+        if ((obj != entry) && elm_object_focus_get(entry))
+          {
+             elm_object_focus_set(entry, EINA_FALSE);
+             elm_entry_input_panel_hide(obj);
+             return;
+          }
+     }
+   entry = elm_object_part_content_get(popup_mod->popup_field[ELM_DATETIME_MONTH],
+                                       "elm.swallow.entry");
+   if (obj == entry)
+     {
+        value = (int)elm_spinner_value_get(popup_mod->popup_field[ELM_DATETIME_MONTH]) - 1;
+        elm_object_text_set(obj, month_arr[value]);
+     }
+   elm_entry_select_all(obj);
+}
+
+static void
+_entry_unfocused_cb(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Popup_Module_Data *popup_mod;
+
+   popup_mod = (Popup_Module_Data *)data;
+   if (!popup_mod) return;
+
+   // TODO: entry_unfocused code
+}
+
+static void
+_adjust_max_days(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Popup_Module_Data *popup_mod;
+   int year, month, max_days;
+
+   popup_mod = (Popup_Module_Data *)data;
+   if (!popup_mod) return;
+
+   year = (int)elm_spinner_value_get(popup_mod->popup_field[ELM_DATETIME_YEAR]);
+   month = (int)elm_spinner_value_get(popup_mod->popup_field[ELM_DATETIME_MONTH]) - 1;
+
+   max_days = days_in_month[month];
+  // if ((year % 4 == 0) && (year % 100 != 0 || year % 400 == 0)&& (month == 1))
+   if (__isleap(year) && (month == 1))
+     max_days += 1;
+
+   elm_spinner_min_max_set(popup_mod->popup_field[ELM_DATETIME_DATE], 1, max_days);
+}
+
+static void
+_year_validity_checking_filter(void *data, Evas_Object *obj, char **text)
+{
+   Popup_Module_Data *popup_mod;
+   Evas_Object *entry;
+   char new_str[BUFF_SIZE] = {0,};
+   int min, max, val = 0, len;
+   char *insert;
+   const char *curr_str;
+
+   EINA_SAFETY_ON_NULL_RETURN(text);
+   popup_mod = (Popup_Module_Data *)data;
+   if (!popup_mod) return;
+
+   insert = *text;
+   len = strlen(elm_object_text_get(obj));
+   if (len < 3) return;
+
+   curr_str = elm_object_text_get(obj);
+   if (curr_str) strncpy(new_str, curr_str, BUFF_SIZE);
+   strncat(new_str, insert, 1);
+   if (new_str[0]) val = atoi(new_str);
+
+   popup_mod->mod_data.field_limit_get(popup_mod->mod_data.base, ELM_DATETIME_YEAR, &min, &max);
+   min += STRUCT_TM_YEAR_BASE_VALUE;
+   max += STRUCT_TM_YEAR_BASE_VALUE;
+
+   if (val <= max)
+     {
+       elm_spinner_value_set(popup_mod->popup_field[ELM_DATETIME_YEAR], val);
+       elm_layout_signal_emit(popup_mod->popup_field[ELM_DATETIME_YEAR],
+                              "elm,action,entry,toggle", "elm");
+       elm_object_focus_set(obj, EINA_FALSE);
+
+       entry = elm_object_part_content_get(popup_mod->popup_field[ELM_DATETIME_MONTH],
+                                           "elm.swallow.entry");
+       if (!elm_object_focus_get(entry))
+         {
+            elm_layout_signal_emit(popup_mod->popup_field[ELM_DATETIME_MONTH],
+                                   "elm,action,entry,toggle", "elm");
+            elm_object_focus_set(entry, EINA_TRUE);
+         }
+     }
+
+   *insert = 0;
+}
+
+static void
+_month_validity_checking_filter(void *data, Evas_Object *obj, char **text)
+{
+   Popup_Module_Data *popup_mod;
+   Evas_Object *entry;
+   char *insert;
+   int min, max, val = 0;
+   char new_str[BUFF_SIZE];
+
+   EINA_SAFETY_ON_NULL_RETURN(text);
+   popup_mod = (Popup_Module_Data *)data;
+   if (!popup_mod) return;
+
+   insert = *text;
+   strncpy(new_str, insert, BUFF_SIZE);
+   if (new_str[0]) val = atoi(new_str) - 1; //tm struct accepts month values from 0 while ISE output starts from 1.
+
+   popup_mod->mod_data.field_limit_get(popup_mod->mod_data.base, ELM_DATETIME_MONTH, &min, &max);
+
+   if ((val >= min) && (val <= max))
+     {
+       elm_spinner_value_set(popup_mod->popup_field[ELM_DATETIME_MONTH], val+1);
+       elm_layout_signal_emit(popup_mod->popup_field[ELM_DATETIME_MONTH],
+                             "elm,action,entry,toggle", "elm");
+       elm_object_focus_set(obj, EINA_FALSE);
+
+       entry = elm_object_part_content_get(popup_mod->popup_field[ELM_DATETIME_DATE],
+                                         "elm.swallow.entry");
+       if (!elm_object_focus_get(entry))
+         {
+            elm_layout_signal_emit(popup_mod->popup_field[ELM_DATETIME_DATE],
+                                 "elm,action,entry,toggle", "elm");
+            elm_object_focus_set(entry, EINA_TRUE);
+         }
+     }
+   *insert = 0;
+}
+
+static void
+_hour_validity_checking_filter(void *data, Evas_Object *obj, char **text)
+{
+   Popup_Module_Data *popup_mod;
+   Evas_Object *entry;
+   char new_str[BUFF_SIZE] = {0,};
+   int val = 0, len;
+   char *insert;
+   const char *curr_str;
+
+   EINA_SAFETY_ON_NULL_RETURN(text);
+
+   popup_mod = (Popup_Module_Data *)data;
+   if (!popup_mod) return;
+
+   insert = *text;
+
+   insert = *text;
+   len = strlen(elm_object_text_get(obj));
+   if (len < 1) return;
+
+   curr_str = elm_object_text_get(obj);
+   if (curr_str) strncpy(new_str, curr_str, BUFF_SIZE);
+   strncat(new_str, insert, 1);
+   if (new_str[0]) val = atoi(new_str);
+
+   if (val > STRUCT_TM_TIME_12HRS_MAX_VALUE)
+     {
+       *insert = 0;
+       return;
+     }
+
+    elm_spinner_value_set(popup_mod->popup_field[ELM_DATETIME_HOUR], val);
+    elm_layout_signal_emit(popup_mod->popup_field[ELM_DATETIME_HOUR],
+                                    "elm,action,entry,toggle", "elm");
+    elm_object_focus_set(obj, EINA_FALSE);
+
+    entry = elm_object_part_content_get(popup_mod->popup_field[ELM_DATETIME_MINUTE],
+                                                 "elm.swallow.entry");
+    if (!elm_object_focus_get(entry))
+      {
+         elm_layout_signal_emit(popup_mod->popup_field[ELM_DATETIME_MINUTE],
+                                         "elm,action,entry,toggle", "elm");
+         elm_object_focus_set(entry, EINA_TRUE);
+      }
+}
+
+static void
+_date_validity_checking_filter(void *data, Evas_Object *obj, char **text)
+{
+   Popup_Module_Data *popup_mod;
+   char new_str[BUFF_SIZE] = {0,};
+   int min, max, val = 0, len;
+   const char *curr_str;
+   char *insert;
+
+   EINA_SAFETY_ON_NULL_RETURN(text);
+   popup_mod = (Popup_Module_Data *)data;
+   if (!popup_mod) return;
+
+   insert = *text;
+   len = strlen(elm_object_text_get(obj));
+   if (len < 1) return;
+
+   curr_str = elm_object_text_get(obj);
+   if (curr_str) strncpy(new_str, curr_str, BUFF_SIZE);
+   strncat(new_str, insert, 1);
+   if (new_str[0]) val = atoi(new_str);
+
+   popup_mod->mod_data.field_limit_get(popup_mod->mod_data.base, ELM_DATETIME_DATE, &min, &max);
+
+   if ((val < min) || (val > max))
+     *insert = 0;
+}
+
+static void
+_minute_validity_checking_filter(void *data, Evas_Object *obj, char **text)
+{
+   Popup_Module_Data *popup_mod;
+   char new_str[BUFF_SIZE];
+   int min, max, val = 0, len;
+   char *insert;
+   const char *curr_str;
+
+   EINA_SAFETY_ON_NULL_RETURN(text);
+   popup_mod = (Popup_Module_Data *)data;
+   if (!popup_mod) return;
+
+   insert = *text;
+   len = strlen(elm_object_text_get(obj));
+   if (len < 1) return;
+
+   curr_str = elm_object_text_get(obj);
+   if (curr_str) strncpy(new_str, curr_str, BUFF_SIZE);
+   strncat(new_str, insert, 1);
+   if (new_str[0]) val = atoi(new_str);
+
+   popup_mod->mod_data.field_limit_get(popup_mod->mod_data.base, ELM_DATETIME_MINUTE, &min, &max);
+
+   if ((val < min) || (val > max))
+     *insert = 0;
+}
+
+static void
+_set_spinner_entry_filter(Popup_Module_Data *popup_mod)
+{
+   Evas_Object *spinner, *entry;
+   char buf[BUFF_SIZE];
+   int idx, value;
+   static Elm_Entry_Filter_Accept_Set digits_filter_data;
+   static Elm_Entry_Filter_Limit_Size limit_filter_data;
+
+   if (!popup_mod) return;
+
+   digits_filter_data.accepted = "0123456789";
+   digits_filter_data.rejected = NULL;
+
+   limit_filter_data.max_byte_count = 0;
+
+   for (idx = 0; idx < DATETIME_FIELD_COUNT -1; idx++)
+     {
+       spinner = popup_mod->popup_field[idx];
+       entry = elm_object_part_content_get(spinner, "elm.swallow.entry");
+       if (!entry) continue;
+
+       snprintf(buf, sizeof(buf), "datetime_popup/%s", field_styles[idx]);
+       elm_object_style_set(entry, buf);
+       elm_entry_magnifier_disabled_set(entry, EINA_TRUE);
+       elm_entry_context_menu_disabled_set(entry, EINA_TRUE);
+
+       if (idx == ELM_DATETIME_MONTH)
+         {
+            value = (int)elm_spinner_value_get(popup_mod->popup_field[ELM_DATETIME_MONTH]) - 1;
+            elm_object_text_set(entry, month_arr[value]);
+         }
+
+       elm_entry_markup_filter_append(entry, elm_entry_filter_accept_set, &digits_filter_data);
+
+       if (idx == ELM_DATETIME_MONTH)
+         elm_entry_input_panel_layout_set(entry, ELM_INPUT_PANEL_LAYOUT_MONTH);
+       else
+         elm_entry_input_panel_layout_set(entry, ELM_INPUT_PANEL_LAYOUT_NUMBERONLY);
+
+       if (idx == ELM_DATETIME_YEAR)
+         limit_filter_data.max_char_count = 4;
+       else
+         limit_filter_data.max_char_count = 2;
+
+       elm_entry_markup_filter_append(entry, elm_entry_filter_limit_size, &limit_filter_data);
+
+       evas_object_smart_callback_add(entry, "focused", _entry_focused_cb, popup_mod);
+       evas_object_smart_callback_add(entry, "unfocused", _entry_unfocused_cb, popup_mod);
+       evas_object_smart_callback_add(entry, "activated", _entry_activated_cb, popup_mod);
+       evas_object_smart_callback_add(entry, "clicked", _entry_clicked_cb, popup_mod);
+
+       if (idx == ELM_DATETIME_YEAR)
+         elm_entry_markup_filter_append(entry, _year_validity_checking_filter, popup_mod);
+       else if (idx == ELM_DATETIME_MONTH)
+         elm_entry_markup_filter_append(entry, _month_validity_checking_filter, popup_mod);
+       else if (idx == ELM_DATETIME_DATE)
+         elm_entry_markup_filter_append(entry, _date_validity_checking_filter, popup_mod);
+       else if (idx == ELM_DATETIME_HOUR)
+         elm_entry_markup_filter_append(entry, _hour_validity_checking_filter, popup_mod);
+       else if (idx == ELM_DATETIME_MINUTE)
+         elm_entry_markup_filter_append(entry, _minute_validity_checking_filter, popup_mod);
+     }
+}
+
+static void
+_set_spinner_special_values(Popup_Module_Data *popup_mod)
+{
+   struct tm curr_time;
+   char am_str[BUFF_SIZE] = {0,};
+   char pm_str[BUFF_SIZE] = {0,};
+   const char *fmt = NULL;
+   int month;
+
+   if (!popup_mod) return;
+
+   elm_datetime_value_get(popup_mod->mod_data.base, &curr_time);
+   fmt = popup_mod->mod_data.field_format_get(popup_mod->mod_data.base, ELM_DATETIME_MONTH);
+   for (month = 0; month < TOTAL_NUMBER_OF_MONTHS; month++)
+     {
+         curr_time.tm_mon = month;
+         strftime(month_arr[month], MONTH_STRING_MAX_SIZE, fmt, &curr_time);
+     }
+   for (month = 0; month < 12; month++)
+     elm_spinner_special_value_add(popup_mod->popup_field[ELM_DATETIME_MONTH],
+                                   month + 1, month_arr[month]);
+
+   fmt = popup_mod->mod_data.field_format_get(popup_mod->mod_data.base, ELM_DATETIME_AMPM);
+   if (fmt)
+     {
+        curr_time.tm_hour = 0;
+        strftime(am_str, BUFF_SIZE, fmt, &curr_time);
+        curr_time.tm_hour = 12;
+        strftime(pm_str, BUFF_SIZE, fmt, &curr_time);
+     }
+   if (am_str[0])
+     elm_spinner_special_value_add(popup_mod->popup_field[ELM_DATETIME_AMPM], 0, am_str);
+   else
+     elm_spinner_special_value_add(popup_mod->popup_field[ELM_DATETIME_AMPM], 0, E_("AM"));
+
+   if (pm_str[0])
+     elm_spinner_special_value_add(popup_mod->popup_field[ELM_DATETIME_AMPM], 1, pm_str);
+   else
+     elm_spinner_special_value_add(popup_mod->popup_field[ELM_DATETIME_AMPM], 1, E_("PM"));
+}
+
+static void
+_create_datetime_popup(Popup_Module_Data *popup_mod)
+{
+   Evas_Object *set_btn, *cancel_btn;
+   Evas_Object *spinner;
+   Evas_Object *parent, *widget, *conformant = NULL;
+   char buf[BUFF_SIZE];
+   int idx;
+   const char *widget_type;
+
+   if (!popup_mod) return;
+
+   // add popup to the content of elm_conformant
+   widget = popup_mod->mod_data.base;
+   while(widget != NULL)
+     {
+        parent = elm_widget_parent_get(widget);
+        widget_type = elm_widget_type_get(widget);
+        if (!strcmp(widget_type, "elm_conformant")) conformant = widget;
+        widget = parent;
+   }
+   if (conformant)
+     popup_mod->popup = elm_popup_add(elm_object_content_get(conformant));
+   else
+     popup_mod->popup = elm_popup_add(elm_widget_top_get(popup_mod->mod_data.base));
+
+   evas_object_size_hint_weight_set(popup_mod->popup, EVAS_HINT_EXPAND,
+                           EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(popup_mod->popup, EVAS_HINT_FILL, 0.5);
+
+   set_btn = elm_button_add(popup_mod->popup);
+   elm_object_style_set(set_btn, "popup_button/default");
+   elm_object_text_set(set_btn, E_("Set"));
+   elm_object_part_content_set(popup_mod->popup, "button1", set_btn);
+   evas_object_smart_callback_add(set_btn, "clicked", _popup_set_btn_clicked_cb, popup_mod);
+
+   cancel_btn = elm_button_add(popup_mod->popup);
+   elm_object_style_set(cancel_btn, "popup_button/default");
+   elm_object_text_set(cancel_btn, E_("Cancel"));
+   elm_object_part_content_set(popup_mod->popup, "button2", cancel_btn);
+   evas_object_smart_callback_add(cancel_btn, "clicked", _popup_cancel_btn_clicked_cb, popup_mod);
+
+   popup_mod->date_layout = elm_layout_add(popup_mod->popup);
+   elm_layout_theme_set(popup_mod->date_layout, "layout", "datetime_popup", "date_layout");
+
+   popup_mod->time_layout = elm_layout_add(popup_mod->popup);
+   elm_layout_theme_set(popup_mod->time_layout, "layout", "datetime_popup", "time_layout");
+
+   for (idx = 0; idx < DATETIME_FIELD_COUNT; idx++)
+     {
+       spinner = elm_spinner_add(popup_mod->popup);
+       snprintf(buf, sizeof(buf), "datetime_popup/%s", field_styles[idx]);
+       elm_object_style_set(spinner, buf);
+       elm_spinner_step_set(spinner, 1);
+       elm_spinner_wrap_set(spinner, EINA_TRUE);
+       elm_spinner_label_format_set(spinner, "%02.0f");
+       popup_mod->popup_field[idx] = spinner;
+
+       if (idx < ELM_DATETIME_HOUR)
+         {
+            snprintf(buf, sizeof(buf), "field%d", idx);
+            elm_object_part_content_set(popup_mod->date_layout, buf, spinner);
+         }
+       else
+         {
+            snprintf(buf, sizeof(buf), "field%d", (idx - ELM_DATETIME_HOUR));
+            elm_object_part_content_set(popup_mod->time_layout, buf, spinner);
+         }
+       if (idx < ELM_DATETIME_DATE)
+         evas_object_smart_callback_add(spinner, "changed", _adjust_max_days, popup_mod);
+     }
+   elm_spinner_min_max_set(popup_mod->popup_field[ELM_DATETIME_YEAR], 1902, 2037);
+   elm_spinner_min_max_set(popup_mod->popup_field[ELM_DATETIME_MONTH], 1, 12);
+   elm_spinner_min_max_set(popup_mod->popup_field[ELM_DATETIME_DATE], 1, 31);
+   elm_spinner_min_max_set(popup_mod->popup_field[ELM_DATETIME_HOUR], 1, 12);
+   elm_spinner_min_max_set(popup_mod->popup_field[ELM_DATETIME_MINUTE], 0, 59);
+   elm_spinner_min_max_set(popup_mod->popup_field[ELM_DATETIME_AMPM], 0, 1);
+
+   _set_spinner_special_values(popup_mod);
+
+   _set_spinner_entry_filter(popup_mod);
+
+}
+
+static void
+_field_mouse_down_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
+{
+   Evas_Event_Mouse_Down *ev;
+   Popup_Module_Data *popup_mod;
+
+   ev = event_info;
+   popup_mod = (Popup_Module_Data *)data;
+   if (!popup_mod) return;
+
+   popup_mod->sel_field = obj;
+}
+
+static void
+_field_mouse_up_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
+{
+   Evas_Event_Mouse_Up *ev;
+   Popup_Module_Data *popup_mod;
+
+   ev = event_info;
+   popup_mod = (Popup_Module_Data *)data;
+   if (!popup_mod) return;
+
+   if (!popup_mod->popup)
+    _create_datetime_popup(popup_mod);
+
+   elm_object_signal_emit(popup_mod->sel_field, "elm,state,select", "elm");
+
+   _set_popup_content(popup_mod);
+
+   evas_object_show(popup_mod->popup);
+}
+
+static void
+_access_set(Evas_Object *obj, Elm_Datetime_Field_Type field_type)
+{
+   const char* type = NULL;
+
+   switch (field_type)
+     {
+       case ELM_DATETIME_YEAR:
+        type = "datetime field, year";
+        break;
+
+      case ELM_DATETIME_MONTH:
+        type = "datetime field, month";
+        break;
+
+     case ELM_DATETIME_DATE:
+        type = "datetime field, date";
+        break;
+
+      case ELM_DATETIME_HOUR:
+        type = "datetime field, hour";
+        break;
+
+      case ELM_DATETIME_MINUTE:
+        type = "datetime field, minute";
+        break;
+
+      case ELM_DATETIME_AMPM:
+        type = "datetime field, AM PM";
+        break;
+
+      default:
+        break;
+     }
+
+   _elm_access_text_set
+     (_elm_access_object_get(obj), ELM_ACCESS_TYPE, type);
+   _elm_access_callback_set
+     (_elm_access_object_get(obj), ELM_ACCESS_STATE, NULL, NULL);
+}
+
+// module functions for the specific module type
+EAPI void
+field_value_display(Elm_Datetime_Module_Data *module_data, Evas_Object *obj)
+{
+   Popup_Module_Data *popup_mod;
+   Elm_Datetime_Field_Type  field_type;
+   struct tm curr_time;
+   char buf[BUFF_SIZE] = {0,};
+   const char *fmt;
+
+   popup_mod = (Popup_Module_Data *)module_data;
+   if (!popup_mod || !obj) return;
+
+   elm_datetime_value_get(popup_mod->mod_data.base, &curr_time);
+   field_type = (Elm_Datetime_Field_Type )evas_object_data_get(obj, "_field_type");
+   fmt = popup_mod->mod_data.field_format_get(popup_mod->mod_data.base, field_type);
+   strftime(buf, sizeof(buf), fmt, &curr_time);
+
+   if ((!buf[0]) && ((!strcmp(fmt, "%p")) || (!strcmp(fmt, "%P"))))
+     {
+        if (curr_time.tm_hour < STRUCT_TM_TIME_12HRS_MAX_VALUE) strcpy(buf, E_("AM"));
+        else strcpy(buf, E_("PM"));
+     }
+   elm_object_text_set(obj, buf);
+}
+
+EAPI Evas_Object *
+field_create(Elm_Datetime_Module_Data *module_data, Elm_Datetime_Field_Type field_type)
+{
+   Popup_Module_Data *popup_mod;
+   Evas_Object *field_obj;
+   char buf[BUFF_SIZE];
+
+   popup_mod = (Popup_Module_Data *)module_data;
+   if (!popup_mod) return NULL;
+
+   field_obj = elm_label_add(popup_mod->mod_data.base);
+   evas_object_event_callback_add(field_obj, EVAS_CALLBACK_MOUSE_DOWN,
+                                  _field_mouse_down_cb, popup_mod);
+   evas_object_event_callback_add(field_obj, EVAS_CALLBACK_MOUSE_UP,
+                                   _field_mouse_up_cb, popup_mod);
+
+   snprintf(buf, sizeof(buf), "datetime/%s/default", field_styles[field_type]);
+   elm_object_style_set(field_obj, buf);
+   evas_object_data_set(field_obj, "_field_type", (void *)field_type);
+
+   _access_set(field_obj, field_type);
+
+   return field_obj;
+}
+
+EAPI Elm_Datetime_Module_Data *
+obj_hook(Evas_Object *obj __UNUSED__)
+{
+   Popup_Module_Data *popup_mod;
+
+   popup_mod = ELM_NEW(Popup_Module_Data);
+   if (!popup_mod) return NULL;
+
+   popup_mod->popup = NULL;
+   popup_mod->sel_field = NULL;
+
+   return ((Elm_Datetime_Module_Data*)popup_mod);
+}
+
+EAPI void
+obj_unhook(Elm_Datetime_Module_Data *module_data)
+{
+   Popup_Module_Data *popup_mod;
+
+   popup_mod = (Popup_Module_Data *)module_data;
+   if (!popup_mod) return;
+
+   if (popup_mod->popup)
+     evas_object_del(popup_mod->popup);
+
+   if (popup_mod)
+     {
+        free(popup_mod);
+        popup_mod = NULL;
+     }
+}
+
+EAPI void
+obj_language_change(Elm_Datetime_Module_Data *module_data __UNUSED__)
+{
+   Popup_Module_Data *popup_mod;
+
+   popup_mod = (Popup_Module_Data *)module_data;
+   if (!popup_mod || popup_mod->popup) return;
+
+   _set_spinner_special_values(popup_mod);
+}
+
+EAPI void
+obj_hide(Elm_Datetime_Module_Data *module_data __UNUSED__)
+{
+   // TODO: Default focus - enhance this func. for obj_show/obj_hide like below
+#if 0
+   Popup_Module_Data *popup_mod;
+   int idx;
+   Eina_Bool is_focused = EINA_FALSE; //init with i/p argument
+
+   popup_mod = (Popup_Module_Data *)module_data;
+   if (!popup_mod || popup_mod->popup) return;
+
+   for (idx = 0; idx < DATETIME_FIELD_COUNT; idx++)
+      if (elm_object_focus_get(popup_mod->popup_field[idx]))
+        is_focused = EINA_TRUE;
+
+   if (is_focused)
+     evas_object_show(popup_mod->popup);
+   else
+     evas_object_hide(popup_mod->popup);
+#endif
+}
+
+// module api funcs needed
+EAPI int
+elm_modapi_init(void *m __UNUSED__)
+{
+   return 1; // succeed always
+}
+
+EAPI int
+elm_modapi_shutdown(void *m __UNUSED__)
+{
+   return 1; // succeed always
+}