1 #include <Elementary.h>
5 * @defgroup Datefield Datefield
8 * This is a date editfield. it is used to input date and time using keypad
11 typedef struct _Widget_Data Widget_Data;
36 #define YEAR_MAX_LENGTH 4
37 #define MONTH_MAX_LENGTH 3
38 #define DAY_MAX_LENGTH 2
39 #define TIME_MAX_LENGTH 2
41 #define MONTH_MAXIMUM 12
42 #define HOUR_24H_MAXIMUM 23
43 #define HOUR_12H_MAXIMUM 12
44 #define MIN_MAXIMUM 59
46 static char month_label[12][4] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
51 Evas_Object *date[DATE_MAX];
52 Evas_Object *time[TIME_MAX];
53 Ecore_Event_Handler *handler;
57 int year, month, day, hour, min;
58 int y_max, m_max, d_max;
59 int y_min, m_min, d_min;
62 Eina_Bool time_mode:1;
65 void (*func)(void *data, Evas_Object *obj, int value);
69 static const char *widtype = NULL;
71 static void _del_hook(Evas_Object *obj);
72 static void _theme_hook(Evas_Object *obj);
73 static void _sizing_eval(Evas_Object *obj);
74 static void _on_focus_hook(void *data, Evas_Object *obj);
76 static void _signal_rect_mouse_down(void *data, Evas_Object *obj, const char *emission, const char *source);
77 static void _signal_ampm_mouse_down(void *data, Evas_Object *obj, const char *emission, const char *source);
78 static void _signal_ampm_clicked(void *data, Evas_Object *obj, const char *emission, const char *source);
79 static void _entry_focused_cb(void *data, Evas_Object *obj, void *event_info);
80 static void _entry_unfocused_cb(void *data, Evas_Object *obj, void *event_info);
81 static void _entry_key_up_cb(void *data, Evas *e , Evas_Object *obj , void *event_info);
82 static Eina_Bool _imf_event_commit_cb(void *data, int type, void *event);
83 static void _input_panel_event_callback(void *data, Ecore_IMF_Context *ctx, int value);
85 static void _date_entry_add(Evas_Object *obj);
86 static void _time_entry_add(Evas_Object *obj);
87 static void _date_update(Evas_Object *obj);
88 static Eina_Bool _focus_idler_cb(void *obj);
89 static void _entry_focus_move(Evas_Object *obj, Evas_Object *focus_obj);
90 static Eina_Bool _check_input_done(Evas_Object *obj, Evas_Object *focus_obj, int strlen);
91 static int _maximum_day_get(int year, int month);
92 static int _check_date_boundary(Evas_Object *obj, int num, int flag);
95 _del_hook(Evas_Object *obj)
97 Widget_Data *wd = elm_widget_data_get(obj);
100 ecore_event_handler_del(wd->handler);
106 _on_focus_hook(void *data, Evas_Object *obj)
108 Widget_Data *wd = elm_widget_data_get(obj);
109 if (!wd || !wd->base) return ;
111 if (elm_widget_focus_get(obj)) wd->idler = ecore_idler_add(_focus_idler_cb, obj);
115 _theme_hook(Evas_Object *obj)
117 Widget_Data *wd = elm_widget_data_get(obj);
119 if (!wd || !wd->base) return;
121 if (wd->layout == ELM_DATEFIELD_LAYOUT_DATEANDTIME)
123 _elm_theme_object_set(obj, wd->base, "datefield", "dateandtime", elm_widget_style_get(obj));
125 for (i = 0; i < DATE_MAX; i++)
126 elm_object_style_set(wd->date[i], "datefield/hybrid");
127 for (i = 0; i < TIME_MAX; i++)
128 elm_object_style_set(wd->time[i], "datefield/hybrid");
130 else if (wd->layout == ELM_DATEFIELD_LAYOUT_DATE)
132 _elm_theme_object_set(obj, wd->base, "datefield", "date", elm_widget_style_get(obj));
134 for (i = 0; i < DATE_MAX; i++)
135 elm_object_style_set(wd->date[i], "datefield");
137 for (i = 0; i < TIME_MAX; i++)
138 evas_object_hide(wd->time[i]);
140 else if (wd->layout == ELM_DATEFIELD_LAYOUT_TIME)
142 _elm_theme_object_set(obj, wd->base, "datefield", "time", elm_widget_style_get(obj));
144 for (i = 0; i < TIME_MAX; i++)
145 elm_object_style_set(wd->time[i], "datefield");
147 for (i = 0; i < DATE_MAX; i++)
148 evas_object_hide(wd->date[i]);
151 if (wd->layout == ELM_DATEFIELD_LAYOUT_DATEANDTIME || wd->layout == ELM_DATEFIELD_LAYOUT_DATE)
153 edje_object_part_swallow(wd->base, "elm.swallow.date.year", wd->date[DATE_YEAR]);
154 edje_object_part_swallow(wd->base, "elm.swallow.date.month", wd->date[DATE_MON]);
155 edje_object_part_swallow(wd->base, "elm.swallow.date.day", wd->date[DATE_DAY]);
156 edje_object_part_text_set(wd->base, "elm.text.date.comma", ",");
159 if (wd->layout == ELM_DATEFIELD_LAYOUT_DATEANDTIME || wd->layout == ELM_DATEFIELD_LAYOUT_TIME)
161 edje_object_part_swallow(wd->base, "elm.swallow.time.hour", wd->time[TIME_HOUR]);
162 edje_object_part_swallow(wd->base, "elm.swallow.time.min", wd->time[TIME_MIN]);
163 edje_object_part_text_set(wd->base, "elm.text.colon", ":");
166 edje_object_scale_set(wd->base, elm_widget_scale_get(obj) * _elm_config->scale);
173 _sizing_eval(Evas_Object *obj)
175 Widget_Data *wd = elm_widget_data_get(obj);
176 Evas_Coord minw = -1, minh = -1;
178 edje_object_size_min_calc(wd->base, &minw, &minh);
179 evas_object_size_hint_min_set(obj, minw, minh);
180 evas_object_size_hint_max_set(obj, -1, -1);
184 _signal_ampm_mouse_down(void *data, Evas_Object *obj, const char *emission, const char *source)
186 Widget_Data *wd = elm_widget_data_get(data);
187 Evas_Object *focus_obj;
189 if (!wd || !wd->base) return ;
191 focus_obj = elm_widget_focused_object_get(data);
192 if (focus_obj) elm_object_unfocus(focus_obj);
196 _signal_ampm_clicked(void *data, Evas_Object *obj, const char *emission, const char *source)
198 Widget_Data *wd = elm_widget_data_get(data);
199 if (!wd || !wd->base) return ;
205 edje_object_part_text_set(wd->base, "elm.text.ampm", "PM");
206 wd->hour += HOUR_12H_MAXIMUM;
210 edje_object_part_text_set(wd->base, "elm.text.ampm", "AM");
211 wd->hour -= HOUR_12H_MAXIMUM;
216 _signal_rect_mouse_down(void *data, Evas_Object *obj, const char *emission, const char *source)
218 Widget_Data *wd = elm_widget_data_get(data);
221 if (!strcmp(source, "elm.rect.date.year.over"))
222 elm_object_focus(wd->date[DATE_YEAR]);
223 else if (!strcmp(source, "elm.rect.date.month.over"))
224 elm_object_focus(wd->date[DATE_MON]);
225 else if (!strcmp(source, "elm.rect.date.day.over"))
226 elm_object_focus(wd->date[DATE_DAY]);
227 else if (!strcmp(source, "elm.rect.time.hour.over"))
228 elm_object_focus(wd->time[TIME_HOUR]);
229 else if (!strcmp(source, "elm.rect.time.min.over"))
230 elm_object_focus(wd->time[TIME_MIN]);
231 else if (!strcmp(source, "elm.rect.date.left.pad"))
233 switch (wd->date_format)
235 case DATE_FORMAT_YYDDMM:
236 case DATE_FORMAT_YYMMDD:
237 elm_object_focus(wd->date[DATE_YEAR]);
239 case DATE_FORMAT_MMDDYY:
240 case DATE_FORMAT_MMYYDD:
241 elm_object_focus(wd->date[DATE_MON]);
243 case DATE_FORMAT_DDMMYY:
244 case DATE_FORMAT_DDYYMM:
245 elm_object_focus(wd->date[DATE_DAY]);
248 else if (!strcmp(source, "elm.rect.date.right.pad"))
250 switch (wd->date_format)
252 case DATE_FORMAT_MMDDYY:
253 case DATE_FORMAT_DDMMYY:
254 elm_object_focus(wd->date[DATE_YEAR]);
256 case DATE_FORMAT_DDYYMM:
257 case DATE_FORMAT_YYDDMM:
258 elm_object_focus(wd->date[DATE_MON]);
260 case DATE_FORMAT_YYMMDD:
261 case DATE_FORMAT_MMYYDD:
262 elm_object_focus(wd->date[DATE_DAY]);
268 _focus_idler_cb(void *obj)
270 Widget_Data *wd = elm_widget_data_get(obj);
271 Evas_Object *focus_obj;
273 focus_obj = elm_widget_focused_object_get(obj);
274 if (focus_obj == obj)
276 if (wd->layout == ELM_DATEFIELD_LAYOUT_TIME)
277 elm_object_focus(wd->time[TIME_HOUR]);
279 else if (wd->layout == ELM_DATEFIELD_LAYOUT_DATEANDTIME || wd->layout == ELM_DATEFIELD_LAYOUT_DATE)
281 switch (wd->date_format)
283 case DATE_FORMAT_YYDDMM:
284 case DATE_FORMAT_YYMMDD:
285 elm_object_focus(wd->date[DATE_YEAR]);
287 case DATE_FORMAT_MMDDYY:
288 case DATE_FORMAT_MMYYDD:
289 elm_object_focus(wd->date[DATE_MON]);
291 case DATE_FORMAT_DDMMYY:
292 case DATE_FORMAT_DDYYMM:
293 elm_object_focus(wd->date[DATE_DAY]);
302 _entry_focused_cb(void *data, Evas_Object *obj, void *event_info)
304 Widget_Data *wd = elm_widget_data_get(data);
305 if (!wd || !wd->base) return;
309 ecore_idler_del(wd->idler);
313 if (obj == wd->date[DATE_YEAR])
314 edje_object_signal_emit(wd->base, "elm,state,year,focus,in", "elm");
315 else if (obj == wd->date[DATE_MON])
316 edje_object_signal_emit(wd->base, "elm,state,month,focus,in", "elm");
317 else if (obj == wd->date[DATE_DAY])
318 edje_object_signal_emit(wd->base, "elm,state,day,focus,in", "elm");
319 else if (obj == wd->time[TIME_HOUR])
320 edje_object_signal_emit(wd->base, "elm,state,hour,focus,in", "elm");
321 else if (obj == wd->time[TIME_MIN])
322 edje_object_signal_emit(wd->base, "elm,state,min,focus,in", "elm");
326 _entry_unfocused_cb(void *data, Evas_Object *obj, void *event_info)
328 Widget_Data *wd = elm_widget_data_get(data);
329 char str[YEAR_MAX_LENGTH+1] = {0,};
332 if (!wd || !wd->base) return;
335 if (obj == wd->date[DATE_YEAR])
337 if (strlen(elm_entry_entry_get(wd->date[DATE_YEAR]))) wd->year = atoi(elm_entry_entry_get(wd->date[DATE_YEAR]));
338 wd->year = _check_date_boundary(data, wd->year, DATE_YEAR);
339 sprintf(str, "%d", wd->year);
340 elm_entry_entry_set(wd->date[DATE_YEAR], str);
342 //check month boundary
343 if(wd->month != (num = _check_date_boundary(data, wd->month, DATE_MON)))
346 elm_entry_entry_set(wd->date[DATE_MON], month_label[wd->month-1]);
349 if (wd->day != (num = _check_date_boundary(data, wd->day, DATE_DAY)))
352 sprintf(str, "%d", wd->day);
353 elm_entry_entry_set(wd->date[DATE_DAY], str);
355 edje_object_signal_emit(wd->base, "elm,state,year,focus,out", "elm");
357 else if (obj == wd->date[DATE_MON])
359 if(wd->month != (num = _check_date_boundary(data, wd->month, DATE_MON)))
362 elm_entry_entry_set(wd->date[DATE_MON], month_label[wd->month-1]);
365 if (wd->day != (num = _check_date_boundary(data, wd->day, DATE_DAY)))
368 sprintf(str, "%d", wd->day);
369 elm_entry_entry_set(wd->date[DATE_DAY], str);
371 edje_object_signal_emit(wd->base, "elm,state,month,focus,out", "elm");
373 else if (obj == wd->date[DATE_DAY])
375 if (strlen(elm_entry_entry_get(wd->date[DATE_DAY]))) wd->day = atoi(elm_entry_entry_get(wd->date[DATE_DAY]));
376 wd->day = _check_date_boundary(data, wd->day, DATE_DAY);
377 sprintf(str, "%d", wd->day);
378 elm_entry_entry_set(wd->date[DATE_DAY], str);
379 edje_object_signal_emit(wd->base, "elm,state,day,focus,out", "elm");
381 else if (obj == wd->time[TIME_HOUR])
383 if (strlen(elm_entry_entry_get(wd->time[TIME_HOUR]))) num = atoi(elm_entry_entry_get(wd->time[TIME_HOUR]));
386 if (!wd->time_mode) // 24 mode
388 if (num > HOUR_24H_MAXIMUM) num = HOUR_24H_MAXIMUM;
393 if (num > HOUR_24H_MAXIMUM || num == 0)
395 num = HOUR_12H_MAXIMUM;
398 else if (num > HOUR_12H_MAXIMUM)
400 num -= HOUR_12H_MAXIMUM;
403 wd->hour = (wd->pm == EINA_TRUE)? num + HOUR_12H_MAXIMUM : num;
404 if((wd->hour % 12) == 0) wd->hour -= HOUR_12H_MAXIMUM;
406 if (wd->pm) edje_object_part_text_set(wd->base, "elm.text.ampm", "PM");
407 else edje_object_part_text_set(wd->base, "elm.text.ampm", "AM");
409 sprintf(str, "%02d", num);
410 elm_entry_entry_set(wd->time[TIME_HOUR], str);
411 edje_object_signal_emit(wd->base, "elm,state,hour,focus,out", "elm");
413 else if (obj == wd->time[TIME_MIN])
415 if (strlen(elm_entry_entry_get(wd->time[TIME_MIN]))) wd->min = atoi(elm_entry_entry_get(wd->time[TIME_MIN]));
416 if (wd->min > MIN_MAXIMUM) wd->min = MIN_MAXIMUM;
418 sprintf(str, "%02d", wd->min);
419 elm_entry_entry_set(wd->time[TIME_MIN], str);
420 edje_object_signal_emit(wd->base, "elm,state,min,focus,out", "elm");
422 evas_object_smart_callback_call(data, "changed", NULL);
426 _entry_focus_move(Evas_Object *obj, Evas_Object *focus_obj)
428 Widget_Data *wd = elm_widget_data_get(obj);
432 if (focus_obj == wd->date[DATE_YEAR])
434 switch (wd->date_format)
436 case DATE_FORMAT_DDMMYY:
437 case DATE_FORMAT_MMDDYY:
438 if (wd->layout == ELM_DATEFIELD_LAYOUT_DATEANDTIME)
439 elm_object_focus(wd->time[TIME_HOUR]);
440 else if (wd->layout == ELM_DATEFIELD_LAYOUT_DATE)
441 elm_object_unfocus(wd->date[DATE_YEAR]);
443 case DATE_FORMAT_DDYYMM:
444 case DATE_FORMAT_YYMMDD:
445 elm_object_focus(wd->date[DATE_MON]);
447 case DATE_FORMAT_MMYYDD:
448 case DATE_FORMAT_YYDDMM:
449 elm_object_focus(wd->date[DATE_DAY]);
452 else if (focus_obj == wd->date[DATE_MON])
454 switch (wd->date_format)
456 case DATE_FORMAT_DDYYMM:
457 case DATE_FORMAT_YYDDMM:
458 if (wd->layout == ELM_DATEFIELD_LAYOUT_DATEANDTIME)
459 elm_object_focus(wd->time[TIME_HOUR]);
460 else if (wd->layout == ELM_DATEFIELD_LAYOUT_DATE)
461 elm_object_unfocus(wd->date[DATE_MON]);
463 case DATE_FORMAT_DDMMYY:
464 case DATE_FORMAT_MMYYDD:
465 elm_object_focus(wd->date[DATE_YEAR]);
467 case DATE_FORMAT_MMDDYY:
468 case DATE_FORMAT_YYMMDD:
469 elm_object_focus(wd->date[DATE_DAY]);
472 else if (focus_obj == wd->date[DATE_DAY])
474 switch (wd->date_format)
476 case DATE_FORMAT_YYMMDD:
477 case DATE_FORMAT_MMYYDD:
478 if (wd->layout == ELM_DATEFIELD_LAYOUT_DATEANDTIME)
479 elm_object_focus(wd->time[TIME_HOUR]);
480 else if (wd->layout == ELM_DATEFIELD_LAYOUT_DATE)
481 elm_object_unfocus(wd->date[DATE_DAY]);
483 case DATE_FORMAT_DDYYMM:
484 case DATE_FORMAT_MMDDYY:
485 elm_object_focus(wd->date[DATE_YEAR]);
487 case DATE_FORMAT_DDMMYY:
488 case DATE_FORMAT_YYDDMM:
489 elm_object_focus(wd->date[DATE_MON]);
492 else if (focus_obj == wd->time[TIME_HOUR])
493 elm_object_focus(wd->time[TIME_MIN]);
494 else if (focus_obj == wd->time[TIME_MIN])
495 elm_object_unfocus(wd->time[TIME_MIN]);
499 _check_date_boundary(Evas_Object *obj, int num, int flag)
501 Widget_Data *wd = elm_widget_data_get(obj);
502 if (flag == DATE_YEAR)
504 if (num > wd->y_max) num = wd->y_max;
505 else if (num < wd->y_min) num = wd->y_min;
509 else if (flag == DATE_MON)
511 if (wd->year == wd->y_max && num > wd->m_max) num = wd->m_max;
512 else if (wd->year == wd->y_min && num < wd->m_min) num = wd->m_min;
513 else if (num > MONTH_MAXIMUM) num = MONTH_MAXIMUM;
514 else if (num <= 0) num = 1;
518 else if (flag == DATE_DAY)
520 int day_of_month = _maximum_day_get(wd->year, wd->month);
521 if (wd->year == wd->y_max && wd->month == wd->m_max && num > wd->d_max) num = wd->d_max;
522 else if (wd->year == wd->y_min && wd->month == wd->m_min && num < wd->d_min) num = wd->d_min;
523 else if (num > day_of_month) num = day_of_month;
524 else if (num <= 0) num = 1;
531 _maximum_day_get(int year, int month)
533 int day_of_month = 0;
534 if (year == 0 || month == 0) return 0;
544 if ((!(year % 4) && (year % 100)) || !(year % 400))
558 _check_input_done(Evas_Object *obj, Evas_Object *focus_obj, int strlen)
560 Widget_Data *wd = elm_widget_data_get(obj);
562 if (!wd) return EINA_FALSE;
564 if (focus_obj == wd->date[DATE_YEAR] && strlen == YEAR_MAX_LENGTH)
565 wd->editing = EINA_FALSE;
566 else if (focus_obj == wd->date[DATE_MON] && strlen == MONTH_MAX_LENGTH)
567 wd->editing = EINA_FALSE;
568 else if (focus_obj == wd->date[DATE_DAY])
570 if (strlen == DAY_MAX_LENGTH || atoi(elm_entry_entry_get(focus_obj)) > 3)
571 wd->editing = EINA_FALSE;
573 else if (focus_obj == wd->time[TIME_HOUR])
575 if (strlen == TIME_MAX_LENGTH || atoi(elm_entry_entry_get(focus_obj)) > 2)
576 wd->editing = EINA_FALSE;
578 else if (focus_obj == wd->time[TIME_MIN])
580 if (strlen == TIME_MAX_LENGTH || atoi(elm_entry_entry_get(focus_obj)) > 5)
581 wd->editing = EINA_FALSE;
587 _entry_key_up_cb(void *data, Evas *e , Evas_Object *obj , void *event_info)
589 Evas_Event_Key_Up *ev = (Evas_Event_Key_Up *) event_info;
591 if (!strcmp(ev->keyname, "BackSpace"))
592 elm_entry_entry_set(obj, "");
596 _imf_event_commit_cb(void *data, int type, void *event)
598 Widget_Data *wd = elm_widget_data_get(data);
599 Ecore_IMF_Event_Commit *ev = (Ecore_IMF_Event_Commit *) event;
600 Evas_Object *focus_obj;
601 char str[YEAR_MAX_LENGTH+1] = {0,};
603 if (!wd) return ECORE_CALLBACK_PASS_ON;
604 if (!elm_widget_focus_get(data)) return ECORE_CALLBACK_PASS_ON;
606 focus_obj = elm_widget_focused_object_get(data);
609 elm_entry_entry_set(focus_obj, "");
610 wd->editing = EINA_TRUE;
613 if (focus_obj == wd->date[DATE_MON])
615 wd->month = atoi(ev->str);
616 strcpy(str, month_label[wd->month-1]);
620 strcpy(str, elm_entry_entry_get(focus_obj));
621 str[strlen(str)] = ev->str[0];
623 elm_entry_entry_set(focus_obj, str);
625 if (_check_input_done(data, focus_obj, strlen(str)))
626 _entry_focus_move(data, focus_obj);
628 return ECORE_CALLBACK_DONE;
632 _input_panel_event_callback(void *data, Ecore_IMF_Context *ctx, int value)
634 Widget_Data *wd = elm_widget_data_get(data);
639 wd->func(wd->func_data, data, value);
643 _date_update(Evas_Object *obj)
645 Widget_Data *wd = elm_widget_data_get(obj);
646 char str[YEAR_MAX_LENGTH+1];
648 if (!wd || !wd->base) return;
650 sprintf(str, "%d", wd->year);
651 elm_entry_entry_set(wd->date[DATE_YEAR], str);
653 sprintf(str, "%s", month_label[wd->month-1]);
654 elm_entry_entry_set(wd->date[DATE_MON], str);
656 sprintf(str, "%d", wd->day);
657 elm_entry_entry_set(wd->date[DATE_DAY], str);
659 if (!wd->time_mode) //24 mode
660 sprintf(str, "%d", wd->hour);
663 if (wd->hour >= HOUR_12H_MAXIMUM)
666 edje_object_part_text_set(wd->base, "elm.text.ampm", "PM");
671 edje_object_part_text_set(wd->base, "elm.text.ampm", "AM");
674 if (wd->hour > HOUR_12H_MAXIMUM)
675 sprintf(str, "%02d", wd->hour - HOUR_12H_MAXIMUM);
676 else if (wd->hour == 0)
677 sprintf(str, "%02d", HOUR_12H_MAXIMUM);
679 sprintf(str, "%02d", wd->hour);
681 elm_entry_entry_set(wd->time[TIME_HOUR], str);
683 sprintf(str, "%02d", wd->min);
684 elm_entry_entry_set(wd->time[TIME_MIN], str);
688 _date_entry_add(Evas_Object *obj)
690 Widget_Data *wd = elm_widget_data_get(obj);
695 for (i = 0; i < DATE_MAX; i++)
697 wd->date[i] = elm_entry_add(obj);
698 elm_entry_single_line_set(wd->date[i], EINA_TRUE);
699 elm_entry_context_menu_disabled_set(wd->date[i], EINA_TRUE);
700 if (i == DATE_MON) elm_entry_input_panel_layout_set(wd->date[i], ELM_INPUT_PANEL_LAYOUT_MONTH);
701 else elm_entry_input_panel_layout_set(wd->date[i], ELM_INPUT_PANEL_LAYOUT_NUMBERONLY);
702 evas_object_size_hint_weight_set(wd->date[i], EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
703 evas_object_size_hint_align_set(wd->date[i], EVAS_HINT_FILL, EVAS_HINT_FILL);
704 evas_object_smart_callback_add(wd->date[i], "focused", _entry_focused_cb, obj);
705 evas_object_smart_callback_add(wd->date[i], "unfocused", _entry_unfocused_cb, obj);
706 evas_object_event_callback_add(wd->date[i], EVAS_CALLBACK_KEY_UP, _entry_key_up_cb, obj);
707 elm_widget_sub_object_add(obj, wd->date[i]);
709 elm_entry_maximum_bytes_set(wd->date[DATE_YEAR], YEAR_MAX_LENGTH);
710 elm_entry_maximum_bytes_set(wd->date[DATE_MON], MONTH_MAX_LENGTH);
711 elm_entry_maximum_bytes_set(wd->date[DATE_DAY], DAY_MAX_LENGTH);
715 _time_entry_add(Evas_Object *obj)
717 Widget_Data *wd = elm_widget_data_get(obj);
722 for (i = 0; i < TIME_MAX; i++)
724 wd->time[i] = elm_entry_add(obj);
725 elm_entry_single_line_set(wd->time[i], EINA_TRUE);
726 elm_entry_context_menu_disabled_set(wd->time[i], EINA_TRUE);
727 elm_entry_input_panel_layout_set(wd->time[i], ELM_INPUT_PANEL_LAYOUT_NUMBERONLY);
728 elm_entry_maximum_bytes_set(wd->time[i], TIME_MAX_LENGTH);
729 evas_object_size_hint_weight_set(wd->time[i], EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
730 evas_object_size_hint_align_set(wd->time[i], EVAS_HINT_FILL, EVAS_HINT_FILL);
731 evas_object_smart_callback_add(wd->time[i], "focused", _entry_focused_cb, obj);
732 evas_object_smart_callback_add(wd->time[i], "unfocused", _entry_unfocused_cb, obj);
733 evas_object_event_callback_add(wd->time[i], EVAS_CALLBACK_KEY_UP, _entry_key_up_cb, obj);
734 elm_widget_sub_object_add(obj, wd->time[i]);
739 * Add a new datefield object
741 * @param parent The parent object
742 * @return The new object or NULL if it cannot be created
747 elm_datefield_add(Evas_Object *parent)
753 e = evas_object_evas_get(parent);
755 wd = ELM_NEW(Widget_Data);
756 obj = elm_widget_add(e);
757 ELM_SET_WIDTYPE(widtype, "datefield");
758 elm_widget_type_set(obj, "datefield");
759 elm_widget_sub_object_add(parent, obj);
760 elm_widget_data_set(obj, wd);
761 elm_widget_del_hook_set(obj, _del_hook);
762 elm_widget_theme_hook_set(obj, _theme_hook);
763 elm_widget_on_focus_hook_set( obj, _on_focus_hook, NULL );
764 elm_widget_can_focus_set(obj, EINA_TRUE);
766 wd->base = edje_object_add(e);
767 elm_widget_resize_object_set(obj, wd->base);
768 edje_object_signal_callback_add(wd->base, "mouse,down,1", "elm.rect.date.left.pad", _signal_rect_mouse_down, obj);
769 edje_object_signal_callback_add(wd->base, "mouse,down,1", "elm.rect.date.year.over", _signal_rect_mouse_down, obj);
770 edje_object_signal_callback_add(wd->base, "mouse,down,1", "elm.rect.date.month.over", _signal_rect_mouse_down, obj);
771 edje_object_signal_callback_add(wd->base, "mouse,down,1", "elm.rect.date.day.over", _signal_rect_mouse_down, obj);
772 edje_object_signal_callback_add(wd->base, "mouse,down,1", "elm.rect.date.right.pad", _signal_rect_mouse_down, obj);
774 edje_object_signal_callback_add(wd->base, "mouse,down,1", "elm.rect.time.hour.over", _signal_rect_mouse_down, obj);
775 edje_object_signal_callback_add(wd->base, "mouse,down,1", "elm.rect.time.min.over", _signal_rect_mouse_down, obj);
776 edje_object_signal_callback_add(wd->base, "mouse,down,1", "elm.rect.time.ampm.over", _signal_ampm_mouse_down, obj);
777 edje_object_signal_callback_add(wd->base, "mouse,clicked,1", "elm.rect.time.ampm.over", _signal_ampm_clicked, obj);
779 wd->handler = ecore_event_handler_add(ECORE_IMF_EVENT_COMMIT, _imf_event_commit_cb, obj);
780 _date_entry_add(obj);
781 _time_entry_add(obj);
789 wd->year = wd->y_min;
793 wd->layout = ELM_DATEFIELD_LAYOUT_DATEANDTIME;
794 wd->time_mode = EINA_TRUE;
795 wd->date_format = DATE_FORMAT_MMDDYY;
803 * set layout for the datefield
805 * @param obj The datefield object
806 * @param layout set layout for date/time/dateandtime (default: ELM_DATEFIELD_LAYOUT_DATEANDTIME)
811 elm_datefield_layout_set(Evas_Object *obj, Elm_Datefield_Layout layout)
813 ELM_CHECK_WIDTYPE(obj, widtype);
814 Widget_Data *wd = elm_widget_data_get(obj);
817 if (layout < ELM_DATEFIELD_LAYOUT_TIME ||layout > ELM_DATEFIELD_LAYOUT_DATEANDTIME) return;
819 if (wd->layout != layout)
828 * get layout of the datefield
830 * @param obj The datefield object
831 * @return layout of the datefield
835 EAPI Elm_Datefield_Layout
836 elm_datefield_layout_get(const Evas_Object *obj)
838 ELM_CHECK_WIDTYPE(obj, widtype) 0;
839 Widget_Data *wd = elm_widget_data_get(obj);
847 * Set selected date of the datefield
849 * @param obj The datefield object
850 * @param year The year to set
851 * @param month The month to set
852 * @param day The day to set
853 * @param hour The hours to set (24hour mode - 0~23)
854 * @param min The minutes to set (0~59)
859 elm_datefield_date_set(Evas_Object *obj, int year, int month, int day, int hour, int min)
861 ELM_CHECK_WIDTYPE(obj, widtype);
862 Widget_Data *wd = elm_widget_data_get(obj);
866 wd->year = _check_date_boundary(obj, year, DATE_YEAR);
867 wd->month = _check_date_boundary(obj, month, DATE_MON);
868 wd->day = _check_date_boundary(obj, day, DATE_DAY);
870 if (hour > HOUR_24H_MAXIMUM) wd->hour = HOUR_24H_MAXIMUM;
871 else if (hour < 0) wd->hour = 0;
872 else wd->hour = hour;
874 if (min > MIN_MAXIMUM) wd->min = MIN_MAXIMUM;
875 else if (min < 0) wd->min = 0;
882 * Get selected date of the datefield
884 * @param obj The datefield object
885 * @param year The pointer to the variable get the selected year
886 * @param month The pointer to the variable get the selected month
887 * @param day The pointer to the variable get the selected day
888 * @param hour The pointer to the variable get the selected hour (24hour mode)
889 * @param hour The pointer to the variable get the selected min
894 elm_datefield_date_get(const Evas_Object *obj, int *year, int *month, int *day, int *hour, int *min)
896 ELM_CHECK_WIDTYPE(obj, widtype);
897 Widget_Data *wd = elm_widget_data_get(obj);
914 * Set upper boundary of the datefield
916 * @param obj The datefield object
917 * @param year The year to set
918 * @param month The month to set
919 * @param day The day to set
925 elm_datefield_date_max_set(Evas_Object *obj, int year, int month, int day)
927 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
928 Widget_Data *wd = elm_widget_data_get(obj);
930 Eina_Bool update = EINA_FALSE;
932 if (!wd) return EINA_FALSE;
933 if (month < 1 || month > MONTH_MAXIMUM) return EINA_FALSE;
934 day_of_month = _maximum_day_get(year, month);
935 if (day < 1 || day > day_of_month) return EINA_FALSE;
941 if (wd->year > wd->y_max)
943 wd->year = wd->y_max;
946 if (wd->year == wd->y_max && wd->month > wd->m_max)
948 wd->month = wd->m_max;
951 if (wd->year == wd->y_max && wd->month == wd->m_max && wd->day > wd->d_max)
957 if (update) _date_update(obj);
962 * Get upper boundary of the datefield
964 * @param obj The datefield object
965 * @param year The pointer to the variable get the maximum year
966 * @param month The pointer to the variable get the maximum month
967 * @param day The pointer to the variable get the maximum day
972 elm_datefield_date_max_get(const Evas_Object *obj, int *year, int *month, int *day)
974 ELM_CHECK_WIDTYPE(obj, widtype);
975 Widget_Data *wd = elm_widget_data_get(obj);
988 * Set lower boundary of the datefield
990 * @param obj The datefield object
991 * @param year The year to set
992 * @param month The month to set
993 * @param day The day to set
996 * @ingroup Datepicker
999 elm_datefield_date_min_set(Evas_Object *obj, int year, int month, int day)
1001 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1002 Widget_Data *wd = elm_widget_data_get(obj);
1004 Eina_Bool update = EINA_FALSE;
1006 if (!wd) return EINA_FALSE;
1007 if (month < 1 || month > MONTH_MAXIMUM) return EINA_FALSE;
1008 day_of_month = _maximum_day_get(year, month);
1009 if (day < 1 || day > day_of_month) return EINA_FALSE;
1015 if (wd->year < wd->y_min)
1017 wd->year = wd->y_min;
1020 if (wd->year == wd->y_min && wd->month < wd->m_min)
1022 wd->month = wd->m_min;
1025 if (wd->year == wd->y_min && wd->month == wd->m_min && wd->day < wd->d_min)
1027 wd->day = wd->d_min;
1031 if (update) _date_update(obj);
1036 * Get lower boundary of the datefield
1038 * @param obj The datefield object
1039 * @param year The pointer to the variable get the maximum year
1040 * @param month The pointer to the variable get the maximum month
1041 * @param day The pointer to the variable get the maximum day
1043 * @ingroup Datefield
1046 elm_datefield_date_min_get(const Evas_Object *obj, int *year, int *month, int *day)
1048 ELM_CHECK_WIDTYPE(obj, widtype);
1049 Widget_Data *wd = elm_widget_data_get(obj);
1062 * Set if the datefield show hours in military or am/pm mode
1064 * @param obj The datefield object
1065 * @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
1067 * @ingroup Datefield
1070 elm_datefield_time_mode_set(Evas_Object *obj, Eina_Bool mode)
1072 ELM_CHECK_WIDTYPE(obj, widtype);
1073 Widget_Data *wd = elm_widget_data_get(obj);
1077 if (wd->time_mode != mode)
1079 char str[YEAR_MAX_LENGTH+1];
1081 wd->time_mode = mode;
1082 if (!wd->time_mode) edje_object_signal_emit(wd->base, "elm,state,mode,24h", "elm");
1083 else edje_object_signal_emit(wd->base, "elm,state,mode,12h", "elm");
1085 if (!wd->time_mode) //24 mode
1086 sprintf(str, "%d", wd->hour);
1089 if (wd->hour >= HOUR_12H_MAXIMUM)
1092 edje_object_part_text_set(wd->base, "elm.text.ampm", "PM");
1096 wd->pm = EINA_FALSE;
1097 edje_object_part_text_set(wd->base, "elm.text.ampm", "AM");
1100 if (wd->hour > HOUR_12H_MAXIMUM)
1101 sprintf(str, "%d", wd->hour - HOUR_12H_MAXIMUM);
1102 else if (wd->hour == 0)
1103 sprintf(str, "%d", HOUR_12H_MAXIMUM);
1105 sprintf(str, "%d", wd->hour);
1107 elm_entry_entry_set(wd->time[TIME_HOUR], str);
1112 * get time mode of the datefield
1114 * @param obj The datefield object
1115 * @return time mode (EINA_TRUE: 12hour mode / EINA_FALSE: 24hour mode)
1117 * @ingroup Datefield
1120 elm_datefield_time_mode_get(const Evas_Object *obj)
1122 ELM_CHECK_WIDTYPE(obj, widtype);
1123 Widget_Data *wd = elm_widget_data_get(obj);
1125 if (!wd) return EINA_FALSE;
1127 return wd->time_mode;
1131 * Set date format of datefield
1133 * @param obj The datefield object
1134 * @param fmt The date format, ex) yymmdd. Default value is mmddyy.
1136 * @ingroup Datefield
1139 elm_datefield_date_format_set(Evas_Object *obj, const char *fmt)
1141 ELM_CHECK_WIDTYPE(obj, widtype);
1142 Widget_Data *wd = elm_widget_data_get(obj);
1143 char sig[32] = "elm,state,format,";
1146 if (!wd || !fmt) return;
1150 sig[j++] = tolower(fmt[i++]);
1153 edje_object_signal_emit(wd->base, sig, "elm");
1155 if (strstr(sig, "yymmdd")) wd->date_format = DATE_FORMAT_YYMMDD;
1156 else if (strstr(sig, "yyddmm")) wd->date_format = DATE_FORMAT_YYDDMM;
1157 else if (strstr(sig, "mmyydd")) wd->date_format = DATE_FORMAT_MMYYDD;
1158 else if (strstr(sig, "mmddyy")) wd->date_format = DATE_FORMAT_MMDDYY;
1159 else if (strstr(sig, "ddyymm")) wd->date_format = DATE_FORMAT_DDYYMM;
1160 else if (strstr(sig, "ddmmyy")) wd->date_format = DATE_FORMAT_DDMMYY;
1164 * get date format of the datefield
1166 * @param obj The datefield object
1167 * @return date format string. ex) yymmdd
1169 * @ingroup Datefield
1172 elm_datefield_date_format_get(const Evas_Object *obj)
1174 ELM_CHECK_WIDTYPE(obj, widtype);
1175 Widget_Data *wd = elm_widget_data_get(obj);
1177 switch (wd->date_format)
1179 case DATE_FORMAT_YYMMDD: return "yymmdd";
1180 case DATE_FORMAT_YYDDMM: return "yyddmm";
1181 case DATE_FORMAT_MMYYDD: return "mmyydd";
1182 case DATE_FORMAT_MMDDYY: return "mmddyy";
1183 case DATE_FORMAT_DDYYMM: return "ddyymm";
1184 case DATE_FORMAT_DDMMYY: return "ddmmyy";
1189 * Add a callback function for input panel state
1191 * @param obj The datefield object
1192 * @param func The function to be called when the event is triggered (value will be the Ecore_IMF_Input_Panel_State)
1193 * @param data The data pointer to be passed to @p func
1195 * @ingroup Datefield
1198 elm_datefield_input_panel_state_callback_add(Evas_Object *obj, void (*pEventCallbackFunc) (void *data, Evas_Object *obj, int value), void *data)
1200 ELM_CHECK_WIDTYPE(obj, widtype);
1201 Widget_Data *wd = elm_widget_data_get(obj);
1206 if (wd->func && (wd->func != pEventCallbackFunc))
1207 elm_datefield_input_panel_state_callback_del(obj, wd->func);
1209 if (wd->func != pEventCallbackFunc)
1211 wd->func = pEventCallbackFunc;
1212 wd->func_data = data;
1214 for (i = 0; i < DATE_MAX; i++)
1215 ecore_imf_context_input_panel_event_callback_add(
1216 elm_entry_imf_context_get(wd->date[i]), ECORE_IMF_INPUT_PANEL_STATE_EVENT, _input_panel_event_callback, obj);
1218 for (i = 0; i < TIME_MAX; i++)
1219 ecore_imf_context_input_panel_event_callback_add(
1220 elm_entry_imf_context_get(wd->time[i]), ECORE_IMF_INPUT_PANEL_STATE_EVENT, _input_panel_event_callback, obj);
1225 * Delete a callback function for input panel state
1227 * @param obj The datefield object
1228 * @param func The function to be called when the event is triggered
1230 * @ingroup Datefield
1233 elm_datefield_input_panel_state_callback_del(Evas_Object *obj, void (*pEventCallbackFunc) (void *data, Evas_Object *obj, int value))
1235 ELM_CHECK_WIDTYPE(obj, widtype);
1236 Widget_Data *wd = elm_widget_data_get(obj);
1241 if (wd->func && wd->func == pEventCallbackFunc)
1243 for (i = 0; i < DATE_MAX; i++)
1244 ecore_imf_context_input_panel_event_callback_del(
1245 elm_entry_imf_context_get(wd->date[i]), ECORE_IMF_INPUT_PANEL_STATE_EVENT, _input_panel_event_callback);
1247 for (i = 0; i < TIME_MAX; i++)
1248 ecore_imf_context_input_panel_event_callback_del(
1249 elm_entry_imf_context_get(wd->time[i]), ECORE_IMF_INPUT_PANEL_STATE_EVENT, _input_panel_event_callback);
1252 wd->func_data = NULL;