[elm_datefield]bug fix regarding signals
[framework/uifw/elementary.git] / src / lib / elm_datefield.c
1 #include <Elementary.h>
2 #include "elm_priv.h"
3
4 /**
5  * @defgroup Datefield Datefield
6  * @ingroup Elementary
7  *
8  * This is a date editfield. it is used to input date and time using keypad
9  */
10
11 typedef struct _Widget_Data Widget_Data;
12
13 enum {
14         DATE_YEAR,
15         DATE_MON,
16         DATE_DAY,
17         DATE_MAX
18 };
19
20 enum {
21         TIME_HOUR,
22         TIME_MIN,
23         TIME_MAX
24 };
25
26 #define YEAR_MAX_LENGTH 4
27 #define MONTH_MAX_LENGTH        3
28 #define DAY_MAX_LENGTH          2
29 #define TIME_MAX_LENGTH 2
30
31 #define YEAR_MAXIMUM            2099
32 #define YEAR_MINIMUM            1900
33 #define HOUR_24H_MAXIMUM        24
34 #define HOUR_12H_MAXIMUM        12
35 #define MIN_MAXIMUM             59
36
37 static char month_label[13][4] = {"", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
38
39 struct _Widget_Data
40 {
41         Evas_Object *base;      
42         Evas_Object *date[DATE_MAX];
43         Evas_Object *time[TIME_MAX];
44         Ecore_Event_Handler *handler;
45         int layout;
46
47         int year, month, day, hour, min;
48         Eina_Bool pm:1;
49         Eina_Bool time_mode:1;
50         Eina_Bool editing:1;
51 };
52
53 static const char *widtype = NULL;
54
55 static void _del_hook(Evas_Object *obj);
56 static void _theme_hook(Evas_Object *obj);
57 static void _sizing_eval(Evas_Object *obj);
58 static void _on_focus_hook(void *data, Evas_Object *obj);
59
60 static void _signal_rect_mouse_down(void *data, Evas_Object *obj, const char *emission, const char *source);
61 static void _signal_ampm_mouse_down(void *data, Evas_Object *obj, const char *emission, const char *source);
62 static void _signal_ampm_clicked(void *data, Evas_Object *obj, const char *emission, const char *source);
63 static void _entry_focused_cb(void *data, Evas_Object *obj, void *event_info);
64 static void _entry_unfocused_cb(void *data, Evas_Object *obj, void *event_info);
65 static int _imf_event_commit_cb(void *data, int type, void *event);
66
67 static void _date_entry_add(Evas_Object *obj);
68 static void _time_entry_add(Evas_Object *obj);
69 static void _date_update(Evas_Object *obj);
70 static void _entry_focus_move(Evas_Object *obj, Evas_Object *focus_obj);
71 static Eina_Bool _check_input_done(Evas_Object *obj, Evas_Object *focus_obj, int strlen);
72 static int _maximum_day_get(int year, int month);
73
74 static void
75 _del_hook(Evas_Object *obj)
76 {
77         ELM_CHECK_WIDTYPE(obj, widtype);
78         Widget_Data *wd = elm_widget_data_get(obj);
79         if (!wd) return ;       
80
81         ecore_event_handler_del(wd->handler);
82                 
83         free(wd);
84 }
85
86 static void
87 _on_focus_hook(void *data, Evas_Object *obj)
88 {
89         ELM_CHECK_WIDTYPE(obj, widtype);
90         Widget_Data *wd = elm_widget_data_get(obj);
91         if (!wd || !wd->base) return ;  
92
93         if (!elm_widget_focus_get(obj))
94                 edje_object_signal_emit(wd->base, "elm,state,focus,out", "elm");
95 }
96
97 static void
98 _theme_hook(Evas_Object *obj)
99 {
100         Widget_Data *wd = elm_widget_data_get(obj);
101         int i;
102         if (!wd || !wd->base) return;
103
104         if (wd->layout == ELM_DATEFIELD_LAYOUT_DATEANDTIME)
105         {
106                 _elm_theme_object_set(obj, wd->base, "datefield", "dateandtime", elm_widget_style_get(obj));
107
108                 for (i = 0; i < DATE_MAX; i++)
109                         elm_object_style_set(wd->date[i], "datefield/hybrid");
110                 for (i = 0; i < TIME_MAX; i++)
111                         elm_object_style_set(wd->time[i], "datefield/hybrid");
112         }
113         else if (wd->layout == ELM_DATEFIELD_LAYOUT_DATE)
114         {
115                 _elm_theme_object_set(obj, wd->base, "datefield", "date", elm_widget_style_get(obj));
116
117                 for (i = 0; i < DATE_MAX; i++)
118                         elm_object_style_set(wd->date[i], "datefield");
119         }
120         else if (wd->layout == ELM_DATEFIELD_LAYOUT_TIME)
121         {
122                 _elm_theme_object_set(obj, wd->base, "datefield", "time", elm_widget_style_get(obj));
123
124                 for (i = 0; i < TIME_MAX; i++)
125                         elm_object_style_set(wd->time[i], "datefield");
126         }
127
128         if (wd->layout == ELM_DATEFIELD_LAYOUT_DATEANDTIME || wd->layout == ELM_DATEFIELD_LAYOUT_DATE)
129         {
130                 edje_object_part_swallow(wd->base, "elm.swallow.date.year", wd->date[DATE_YEAR]);
131                 edje_object_part_swallow(wd->base, "elm.swallow.date.month", wd->date[DATE_MON]);
132                 edje_object_part_swallow(wd->base, "elm.swallow.date.day", wd->date[DATE_DAY]);
133                 edje_object_part_text_set(wd->base, "elm.text.date.comma", ",");        
134         }
135         
136         if (wd->layout == ELM_DATEFIELD_LAYOUT_DATEANDTIME || wd->layout == ELM_DATEFIELD_LAYOUT_TIME)
137         {
138                 edje_object_part_swallow(wd->base, "elm.swallow.time.hour", wd->time[TIME_HOUR]);
139                 edje_object_part_swallow(wd->base, "elm.swallow.time.min", wd->time[TIME_MIN]);
140                 edje_object_part_text_set(wd->base, "elm.text.colon", ":");
141         }
142
143         edje_object_scale_set(wd->base, elm_widget_scale_get(obj) * _elm_config->scale);
144         
145         _date_update(obj);      
146         _sizing_eval(obj);
147 }
148
149 static void
150 _sizing_eval(Evas_Object *obj)
151 {
152         Widget_Data *wd = elm_widget_data_get(obj);
153         Evas_Coord minw = -1, minh = -1;
154
155         edje_object_size_min_calc(wd->base, &minw, &minh);
156         evas_object_size_hint_min_set(obj, minw, minh);
157         evas_object_size_hint_max_set(obj, -1, -1);
158 }
159
160 static void
161 _signal_ampm_mouse_down(void *data, Evas_Object *obj, const char *emission, const char *source)
162 {
163         ELM_CHECK_WIDTYPE(data, widtype);
164         Widget_Data *wd = elm_widget_data_get(data);
165         Evas_Object *focus_obj;
166         
167         if (!wd || !wd->base) return ;  
168
169         focus_obj = elm_widget_focused_object_get(data);
170         if (focus_obj) elm_object_unfocus(focus_obj);
171         edje_object_signal_emit(wd->base, "elm,state,focus,out", "elm");
172 }
173
174 static void
175 _signal_ampm_clicked(void *data, Evas_Object *obj, const char *emission, const char *source)
176 {
177         ELM_CHECK_WIDTYPE(data, widtype);
178         Widget_Data *wd = elm_widget_data_get(data);
179         if (!wd || !wd->base) return ;  
180
181         printf("[%s][%d]\n", __FUNCTION__, __LINE__);
182
183         wd->pm = !wd->pm;
184
185         if (wd->pm)
186         {
187         printf("[%s][%d]\n", __FUNCTION__, __LINE__);
188
189                 edje_object_part_text_set(wd->base, "elm.text.ampm", "PM");
190                 wd->hour += HOUR_12H_MAXIMUM;
191         }
192         else
193         {
194         printf("[%s][%d]\n", __FUNCTION__, __LINE__);
195
196                 edje_object_part_text_set(wd->base, "elm.text.ampm", "AM");
197                 wd->hour -= HOUR_12H_MAXIMUM;
198         }
199 }
200
201 static void
202 _signal_rect_mouse_down(void *data, Evas_Object *obj, const char *emission, const char *source)
203 {
204         ELM_CHECK_WIDTYPE(data, widtype);
205         Widget_Data *wd = elm_widget_data_get(data);
206         if (!wd || !wd->base) return ;
207
208         if (!strcmp(source, "elm.rect.date.year.over") || !strcmp(source, "elm.rect.date.right.pad"))
209                 elm_object_focus(wd->date[DATE_YEAR]);
210         else if (!strcmp(source, "elm.rect.date.month.over") || !strcmp(source, "elm.rect.date.left.pad"))
211                 elm_object_focus(wd->date[DATE_MON]);
212         else if (!strcmp(source, "elm.rect.date.day.over"))
213                 elm_object_focus(wd->date[DATE_DAY]);
214         else if (!strcmp(source, "elm.rect.time.hour.over"))
215                 elm_object_focus(wd->time[TIME_HOUR]);
216         else if (!strcmp(source, "elm.rect.time.min.over"))
217                 elm_object_focus(wd->time[TIME_MIN]);
218 }
219
220 static void
221 _entry_focused_cb(void *data, Evas_Object *obj, void *event_info)
222 {
223         ELM_CHECK_WIDTYPE(data, widtype);
224         Widget_Data *wd = elm_widget_data_get(data);
225         if (!wd || !wd->base) return ;
226
227         if (elm_widget_focus_get(data))
228                 edje_object_signal_emit(wd->base, "elm,state,focus,in", "elm");
229
230         if (obj == wd->date[DATE_YEAR])
231                 edje_object_signal_emit(wd->base, "elm,state,year,focus,in", "elm");
232         else if (obj == wd->date[DATE_MON])
233                 edje_object_signal_emit(wd->base, "elm,state,month,focus,in", "elm");
234         else if (obj == wd->date[DATE_DAY])
235                 edje_object_signal_emit(wd->base, "elm,state,day,focus,in", "elm");
236         else if (obj == wd->time[TIME_HOUR])
237                 edje_object_signal_emit(wd->base, "elm,state,hour,focus,in", "elm");
238         else if (obj == wd->time[TIME_MIN])
239                 edje_object_signal_emit(wd->base, "elm,state,min,focus,in", "elm");
240 }
241
242 static void
243 _entry_unfocused_cb(void *data, Evas_Object *obj, void *event_info)
244 {
245         ELM_CHECK_WIDTYPE(data, widtype);
246         Widget_Data *wd = elm_widget_data_get(data);
247         char str[YEAR_MAX_LENGTH+1] = {0,};
248         int num = 0;
249         
250         if (!wd || !wd->base) return ;
251
252         wd->editing = FALSE;
253
254         if (obj == wd->date[DATE_YEAR])
255         {
256                 num = atoi(elm_entry_entry_get(wd->date[DATE_YEAR]));
257                 if (num > YEAR_MAXIMUM) sprintf(str, "%d", YEAR_MAXIMUM);
258                 else if (num < YEAR_MINIMUM) sprintf(str, "%d", YEAR_MINIMUM);
259                 else sprintf(str, "%d", num);
260
261                 elm_entry_entry_set(wd->date[DATE_YEAR], str);
262                 wd->year = atoi(elm_entry_entry_get(wd->date[DATE_YEAR]));
263                 edje_object_signal_emit(wd->base, "elm,state,year,focus,out", "elm");
264         }
265         else if (obj == wd->date[DATE_MON])
266         {
267                 edje_object_signal_emit(wd->base, "elm,state,month,focus,out", "elm");
268         }       
269         else if (obj == wd->date[DATE_DAY])
270         {
271                 char *entry_str = elm_entry_entry_get(wd->date[DATE_DAY]);
272                 int day_of_month = _maximum_day_get(wd->year, wd->month);
273                 
274                 num = atoi(entry_str);
275                 if (num > day_of_month) sprintf(str, "%d", day_of_month);
276                 else if (entry_str[0] == '0') 
277                 {
278                         str[0] = (entry_str[1] == '0' || entry_str[1] == '\0')? '1' : entry_str[1];
279                         str[1] = '\0';
280                 }
281                 else sprintf(str, "%d", num);
282
283                 elm_entry_entry_set(wd->date[DATE_DAY], str);
284                 wd->day = atoi(elm_entry_entry_get(wd->date[DATE_DAY]));
285                 edje_object_signal_emit(wd->base, "elm,state,day,focus,out", "elm");
286         }
287         else if (obj == wd->time[TIME_HOUR])
288         {
289                 char *entry_str = elm_entry_entry_get(wd->time[TIME_HOUR]);
290                 
291                 num = atoi(entry_str);
292                 if (!wd->time_mode)  //24h mode
293                 {
294                         if (num > HOUR_24H_MAXIMUM) sprintf(str, "%d", HOUR_24H_MAXIMUM);
295                         else if (entry_str[0] == '0') 
296                         {
297                                 str[0] = (entry_str[1] == '\0')? '0' : entry_str[1];
298                                 str[1] = '\0';
299                         }
300                         else sprintf(str, "%d", num);
301
302                         elm_entry_entry_set(wd->time[TIME_HOUR], str);
303                         wd->hour = atoi(elm_entry_entry_get(wd->time[TIME_HOUR]));
304                         edje_object_signal_emit(wd->base, "elm,state,hour,focus,out", "elm");
305                 }
306                 else  //12h mode
307                 {
308                         if (num > HOUR_12H_MAXIMUM) 
309                         {
310                                 num -= HOUR_12H_MAXIMUM;
311                                 wd->pm = EINA_TRUE;
312                         }
313                         if (num > HOUR_12H_MAXIMUM) sprintf(str, "%d", HOUR_12H_MAXIMUM);
314                         else if (entry_str[0] == '0') 
315                         {
316                                 str[0] = (entry_str[1] == '\0')? '0' : entry_str[1];
317                                 str[1] = '\0';
318                         }
319                         else sprintf(str, "%d", num);
320
321                         elm_entry_entry_set(wd->time[TIME_HOUR], str);
322                         if (wd->pm) edje_object_part_text_set(wd->base, "elm.text.ampm", "PM");
323                         else edje_object_part_text_set(wd->base, "elm.text.ampm", "AM");
324                         
325                         wd->hour = (wd->pm == EINA_TRUE)? atoi(elm_entry_entry_get(wd->time[TIME_HOUR])) + HOUR_12H_MAXIMUM : atoi(elm_entry_entry_get(wd->time[TIME_HOUR]));
326                         if((wd->hour % 12) == 0) wd->hour -= HOUR_12H_MAXIMUM;
327                         edje_object_signal_emit(wd->base, "elm,state,hour,focus,out", "elm");
328                 }       
329         }
330         else if (obj == wd->time[TIME_MIN])
331         {
332                 num = atoi(elm_entry_entry_get(wd->time[TIME_MIN]));
333                 if (num > MIN_MAXIMUM) sprintf(str, "%d", MIN_MAXIMUM);
334                 else sprintf(str, "%d", num);
335
336                 elm_entry_entry_set(wd->time[TIME_MIN], str);
337                 wd->min = atoi(elm_entry_entry_get(wd->time[TIME_MIN]));
338                 edje_object_signal_emit(wd->base, "elm,state,min,focus,out", "elm");
339                 edje_object_signal_emit(wd->base, "elm,state,focus,out", "elm");
340         }
341 }
342
343 static void 
344 _entry_focus_move(Evas_Object *obj, Evas_Object *focus_obj)
345 {
346         ELM_CHECK_WIDTYPE(obj, widtype);
347         Widget_Data *wd = elm_widget_data_get(obj);
348         if (!wd || !wd->base) return ;
349
350         if (focus_obj == wd->date[DATE_YEAR])
351         {
352                 if (wd->layout == ELM_DATEFIELD_LAYOUT_DATEANDTIME)
353                         elm_object_focus(wd->time[TIME_HOUR]);
354                 else if (wd->layout == ELM_DATEFIELD_LAYOUT_DATE)
355                         elm_object_unfocus(wd->date[DATE_YEAR]);
356         }
357         else if (focus_obj == wd->date[DATE_MON])
358                 elm_object_focus(wd->date[DATE_DAY]);
359         else if (focus_obj == wd->date[DATE_DAY])
360                 elm_object_focus(wd->date[DATE_YEAR]);
361         else if (focus_obj == wd->time[TIME_HOUR])
362                 elm_object_focus(wd->time[TIME_MIN]);
363         else if (focus_obj == wd->time[TIME_MIN])
364                 elm_object_unfocus(wd->time[TIME_MIN]);
365 }
366
367 static int
368 _maximum_day_get(int year, int month)
369 {
370         int day_of_month = 0;
371         if (year == 0 || month == 0) return 0;
372
373         switch (month) {
374                 case 4: 
375                 case 6: 
376                 case 9: 
377                 case 11:
378                         day_of_month = 30;
379                         break;
380                 case 2:
381                         if ((!(year % 4) && (year % 100)) || !(year % 400))
382                                 day_of_month = 29;
383                         else
384                                 day_of_month = 28;
385                         break;
386                 default:
387                         day_of_month = 31;
388                         break;
389         }
390
391         return day_of_month;
392 }
393
394 static Eina_Bool 
395 _check_input_done(Evas_Object *obj, Evas_Object *focus_obj, int strlen)
396 {
397         ELM_CHECK_WIDTYPE(obj, widtype);
398         Widget_Data *wd = elm_widget_data_get(obj);
399         if (!wd || !wd->base) return EINA_FALSE;
400
401         if (focus_obj == wd->date[DATE_YEAR] && strlen == YEAR_MAX_LENGTH)
402                 wd->editing = EINA_FALSE;
403         else if (focus_obj == wd->date[DATE_MON] && strlen == MONTH_MAX_LENGTH)
404                 wd->editing = EINA_FALSE;
405         else if (focus_obj == wd->date[DATE_DAY] && strlen == DAY_MAX_LENGTH)
406                 wd->editing = EINA_FALSE;
407         else if (focus_obj == wd->time[TIME_HOUR])
408         {       
409                 if (strlen == TIME_MAX_LENGTH || atoi(elm_entry_entry_get(focus_obj)) > 2)
410                         wd->editing = EINA_FALSE;
411         }
412         else if (focus_obj == wd->time[TIME_MIN] && strlen == TIME_MAX_LENGTH) 
413                 wd->editing = EINA_FALSE;
414
415         return !wd->editing;
416 }
417
418 static int 
419 _imf_event_commit_cb(void *data, int type, void *event)
420 {
421         ELM_CHECK_WIDTYPE(data, widtype);
422         Widget_Data *wd = elm_widget_data_get(data);
423         Ecore_IMF_Event_Commit *ev = (Ecore_IMF_Event_Commit *) event;
424         Evas_Object *focus_obj;
425         char str[YEAR_MAX_LENGTH+1] = {0,};
426
427         if (!wd || !wd->base) return ECORE_CALLBACK_RENEW;
428         if(!elm_widget_focus_get(data)) return ECORE_CALLBACK_RENEW;
429         
430         focus_obj = elm_widget_focused_object_get(data);
431         if (!wd->editing) 
432         {
433                 elm_entry_entry_set(focus_obj, "");
434                 wd->editing = EINA_TRUE;
435         }
436         
437         if (focus_obj == wd->date[DATE_MON])
438         {
439                 wd->month = atoi(ev->str);
440                 strcpy(str, month_label[wd->month]);
441         }
442         else
443         {
444                 strcpy(str, elm_entry_entry_get(focus_obj));
445                 str[strlen(str)] = ev->str[0];
446         }
447         elm_entry_entry_set(focus_obj, str);
448
449         if (_check_input_done(data, focus_obj, strlen(str)))
450                 _entry_focus_move(data, focus_obj);
451
452         return ECORE_CALLBACK_CANCEL;
453 }
454
455 static void
456 _date_update(Evas_Object *obj)
457 {
458         ELM_CHECK_WIDTYPE(obj, widtype);
459         Widget_Data *wd = elm_widget_data_get(obj);
460         char str[YEAR_MAX_LENGTH+1] = {0,};
461
462         if (!wd || !wd->base) return;
463
464         sprintf(str, "%d", wd->year);
465         elm_entry_entry_set(wd->date[DATE_YEAR], str);
466
467         memset(str, 0, YEAR_MAX_LENGTH+1);
468         sprintf(str, "%s", month_label[wd->month]);
469         elm_entry_entry_set(wd->date[DATE_MON], str);
470
471         memset(str, 0, YEAR_MAX_LENGTH+1);
472         sprintf(str, "%d", wd->day);
473         elm_entry_entry_set(wd->date[DATE_DAY], str);
474
475         if (wd->hour >= HOUR_12H_MAXIMUM)
476         {
477                 wd->pm = EINA_TRUE;
478                 edje_object_part_text_set(wd->base, "elm.text.ampm", "PM");
479         }
480         else
481         {
482                 wd->pm = EINA_FALSE;
483                 edje_object_part_text_set(wd->base, "elm.text.ampm", "AM");             
484         }
485
486         memset(str, 0, YEAR_MAX_LENGTH+1);
487         if (wd->time_mode && (wd->hour > HOUR_12H_MAXIMUM))
488                 sprintf(str, "%d", wd->hour - HOUR_12H_MAXIMUM);
489         else if (wd->time_mode && (wd->hour == 0))
490                 sprintf(str, "%d", HOUR_12H_MAXIMUM);
491         else
492                 sprintf(str, "%d", wd->hour);
493         elm_entry_entry_set(wd->time[TIME_HOUR], str);
494
495         memset(str, 0, YEAR_MAX_LENGTH+1);
496         sprintf(str, "%d", wd->min);
497         if (wd->min == 0) str[1] = '0';
498         elm_entry_entry_set(wd->time[TIME_MIN], str);
499 }
500
501 static void 
502 _date_entry_add(Evas_Object *obj)
503 {
504         ELM_CHECK_WIDTYPE(obj, widtype);
505         Widget_Data *wd = elm_widget_data_get(obj);
506         int i;
507         
508         if (!wd) return ;       
509
510         for (i = 0; i < DATE_MAX; i++)
511         {
512                 wd->date[i] = elm_entry_add(obj);
513                 elm_entry_context_menu_disabled_set(wd->date[i], EINA_TRUE);
514                 elm_entry_input_panel_layout_set(wd->date[i], ELM_INPUT_PANEL_LAYOUT_NUMBER);
515                 evas_object_size_hint_weight_set(wd->date[i], EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
516                 evas_object_size_hint_align_set(wd->date[i], EVAS_HINT_FILL, EVAS_HINT_FILL);
517                 evas_object_smart_callback_add(wd->date[i], "focused", _entry_focused_cb, obj);
518                 evas_object_smart_callback_add(wd->date[i], "unfocused", _entry_unfocused_cb, obj);
519                 elm_widget_sub_object_add(obj, wd->date[i]);
520         }
521
522         elm_entry_maximum_bytes_set(wd->date[DATE_YEAR], YEAR_MAX_LENGTH);
523         elm_entry_maximum_bytes_set(wd->date[DATE_MON], MONTH_MAX_LENGTH);
524         elm_entry_maximum_bytes_set(wd->date[DATE_DAY], DAY_MAX_LENGTH);
525 }
526
527 static void 
528 _time_entry_add(Evas_Object *obj)
529 {
530         ELM_CHECK_WIDTYPE(obj, widtype);
531         Widget_Data *wd = elm_widget_data_get(obj);
532         int i;
533         
534         if (!wd) return ;       
535
536         for (i = 0; i < TIME_MAX; i++)
537         {
538                 wd->time[i] = elm_entry_add(obj);
539                 elm_entry_context_menu_disabled_set(wd->time[i], EINA_TRUE);
540                 elm_entry_input_panel_layout_set(wd->time[i], ELM_INPUT_PANEL_LAYOUT_NUMBER);           
541                 elm_entry_maximum_bytes_set(wd->time[i], TIME_MAX_LENGTH);
542                 evas_object_size_hint_weight_set(wd->time[i], EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
543                 evas_object_size_hint_align_set(wd->time[i], EVAS_HINT_FILL, EVAS_HINT_FILL);
544                 evas_object_smart_callback_add(wd->time[i], "focused", _entry_focused_cb, obj);
545                 evas_object_smart_callback_add(wd->time[i], "unfocused", _entry_unfocused_cb, obj);
546                 elm_widget_sub_object_add(obj, wd->time[i]);
547         }
548 }
549
550 /**
551  * Add a new datefield object
552  *
553  * @param parent The parent object
554  * @return The new object or NULL if it cannot be created
555  *
556  * @ingroup Datefield
557  */
558 EAPI Evas_Object *
559 elm_datefield_add(Evas_Object *parent)
560 {
561         Evas_Object *obj;
562         Evas *e;
563         Widget_Data *wd;
564
565         e = evas_object_evas_get(parent);
566         if (!e) return NULL; 
567         wd = ELM_NEW(Widget_Data);
568         obj = elm_widget_add(e); 
569         ELM_SET_WIDTYPE(widtype, "datefield");
570         elm_widget_type_set(obj, "datefield");
571         elm_widget_sub_object_add(parent, obj);
572         elm_widget_data_set(obj, wd);
573         elm_widget_del_hook_set(obj, _del_hook);
574         elm_widget_theme_hook_set(obj, _theme_hook);
575         elm_widget_on_focus_hook_set( obj, _on_focus_hook, NULL );
576         elm_widget_can_focus_set(obj, EINA_TRUE);
577
578         wd->base = edje_object_add(e);
579         elm_widget_resize_object_set(obj, wd->base);
580         edje_object_signal_callback_add(wd->base, "mouse,down,1", "elm.rect.date.left.pad", _signal_rect_mouse_down, obj);
581         edje_object_signal_callback_add(wd->base, "mouse,down,1", "elm.rect.date.year.over", _signal_rect_mouse_down, obj);
582         edje_object_signal_callback_add(wd->base, "mouse,down,1", "elm.rect.date.month.over", _signal_rect_mouse_down, obj);
583         edje_object_signal_callback_add(wd->base, "mouse,down,1", "elm.rect.date.day.over", _signal_rect_mouse_down, obj);      
584         edje_object_signal_callback_add(wd->base, "mouse,down,1", "elm.rect.date.right.pad", _signal_rect_mouse_down, obj);
585
586         edje_object_signal_callback_add(wd->base, "mouse,down,1", "elm.rect.time.hour.over", _signal_rect_mouse_down, obj);
587         edje_object_signal_callback_add(wd->base, "mouse,down,1", "elm.rect.time.min.over", _signal_rect_mouse_down, obj);
588         edje_object_signal_callback_add(wd->base, "mouse,down,1", "elm.rect.time.ampm.over", _signal_ampm_mouse_down, obj);
589         edje_object_signal_callback_add(wd->base, "mouse,clicked,1", "elm.rect.time.ampm.over", _signal_ampm_clicked, obj);
590
591         wd->handler =  ecore_event_handler_add(ECORE_IMF_EVENT_COMMIT, _imf_event_commit_cb, obj);
592         _date_entry_add(obj);
593         _time_entry_add(obj);   
594
595         wd->year = YEAR_MINIMUM;
596         wd->month = 1;
597         wd->day = 1;
598         wd->hour = 0;
599         wd->min = 0;
600         wd->layout = ELM_DATEFIELD_LAYOUT_DATEANDTIME;
601         wd->editing = EINA_FALSE;
602         wd->time_mode = EINA_TRUE;
603         
604         _theme_hook(obj);
605         
606         return obj;
607 }
608
609 /**
610  * Add a new datefield object
611  *
612  * @param parent The parent object
613  * @param layout set layout for date/time/dateandtime (default: ELM_DATEFIELD_LAYOUT_DATEANDTIME)
614  *
615  * @ingroup Datefield
616  */
617 EAPI void
618 elm_datefield_layout_set(Evas_Object *obj, Elm_Datefield_Layout layout)
619 {
620         ELM_CHECK_WIDTYPE(obj, widtype);
621         Widget_Data *wd = elm_widget_data_get(obj);
622         
623         if (!wd) return ;       
624
625         if (wd->layout != layout)
626         {
627                 wd->layout = layout;
628                 _theme_hook(obj);
629         }
630 }
631
632 /**
633  * Set selected date of the datefield
634  *
635  * @param obj The datefield object
636  * @param year The year to set
637  * @param month The month to set
638  * @param day The day to set
639  * @param hour The hours to set (24hour mode)
640  * @param min The minutes to set
641  *
642  * @ingroup Datefield
643  */
644 EAPI void
645 elm_datefield_date_set(Evas_Object *obj, int year, int month, int day, int hour, int min)
646 {
647         ELM_CHECK_WIDTYPE(obj, widtype);
648         Widget_Data *wd = elm_widget_data_get(obj);
649         
650         if (!wd) return ;       
651
652         wd->year = year;
653         wd->month = month;
654         wd->day = day;
655         wd->hour = hour;
656         wd->min = min;
657
658         _date_update(obj);
659 }
660
661 /**
662  * Get selected date of the datefield
663  *
664  * @param obj The datepicker object
665  * @param year The pointer to the variable get the selected year
666  * @param month The pointer to the variable get the selected month
667  * @param day The pointer to the variable get the selected day
668  * @param hour The pointer to the variable get the selected hour (24hour mode)
669  * @param hour The pointer to the variable get the selected min
670  *
671  * @ingroup Datefield
672  */
673 EAPI void
674 elm_datefield_date_get(Evas_Object *obj, int *year, int *month, int *day, int *hour, int *min)
675 {
676         Widget_Data *wd = elm_widget_data_get(obj);
677         if (!wd) return;
678         
679         if (year)
680                 *year = wd->year;
681         if (month)
682                 *month = wd->month;
683         if (day)
684                 *day = wd->day;
685         if (hour)
686                 *hour = wd->hour;
687         if (min)
688                 *min = wd->min;
689 }
690
691 /**
692  * Set if the datefield show hours in military or am/pm mode
693  *
694  * @param obj The datefield object
695  * @param mode option for the hours mode. If true, it is shown as 12h mode, if false, it is shown as 24h mode. Default value is true 
696  *
697  * @ingroup Datefield
698  */
699 EAPI void
700 elm_datefield_time_mode_set(Evas_Object *obj, Eina_Bool mode)
701 {
702         Widget_Data *wd = elm_widget_data_get(obj);
703         if (!wd) return;
704
705         if (wd->time_mode != mode) {
706                 wd->time_mode = mode;
707                 //_update_ampm(obj);
708         }
709 }
710