summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWooHyun Jung <wh0705.jung@samsung.com>2017-10-25 16:42:39 +0900
committerJean-Philippe Andre <jp.andre@samsung.com>2017-10-25 16:50:01 +0900
commit9442f4687cd2eaa202c41254c12f553c463386f5 (patch)
tree4027a64fb882d607958bc15f0f7620ef495cb361
parent40589a92a012e67003b116cd6c559a264b42bc87 (diff)
efl_ui_calendar: create new efl_ui_calendar
Summary: This calendar widget will support basic functionality of calendar. I've separated this widget from elm_calendar since elm_calendar had lots of unuseful things inside. Reviewers: jpeg, singh.amitesh, cedric, CHAN, Jaehyun_Cho Subscribers: cedric, jpeg Differential Revision: https://phab.enlightenment.org/D5346
-rw-r--r--config/default/base.src.in95
-rw-r--r--config/mobile/base.src.in95
-rw-r--r--config/standard/base.src.in95
-rw-r--r--po/POTFILES.in1
-rw-r--r--src/Makefile_Elementary.am5
-rw-r--r--src/bin/elementary/test.c2
-rw-r--r--src/bin/elementary/test_calendar.c56
-rw-r--r--src/lib/elementary/Elementary.h1
-rw-r--r--src/lib/elementary/efl_ui_calendar.c1214
-rw-r--r--src/lib/elementary/efl_ui_calendar.eo149
-rw-r--r--src/lib/elementary/efl_ui_calendar.h57
-rw-r--r--src/lib/elementary/efl_ui_calendar_common.h21
-rw-r--r--src/lib/elementary/efl_ui_calendar_private.h65
13 files changed, 1856 insertions, 0 deletions
diff --git a/config/default/base.src.in b/config/default/base.src.in
index 510e5a0f13..10d7d0e6a5 100644
--- a/config/default/base.src.in
+++ b/config/default/base.src.in
@@ -749,6 +749,101 @@ group "Elm_Config" struct {
749 } 749 }
750 } 750 }
751 group "Elm_Config_Bindings_Widget" struct { 751 group "Elm_Config_Bindings_Widget" struct {
752 value "name" string: "Efl.Ui.Calendar";
753 group "key_bindings" list {
754 group "Elm_Config_Binding_Key" struct {
755 value "context" int: 0;
756 value "key" string: "Prior";
757 value "action" string: "move";
758 value "params" string: "prior";
759 }
760 group "Elm_Config_Binding_Key" struct {
761 value "context" int: 0;
762 value "key" string: "KP_Prior";
763 value "action" string: "move";
764 value "params" string: "prior";
765 }
766 group "Elm_Config_Binding_Key" struct {
767 value "context" int: 0;
768 value "key" string: "Next";
769 value "action" string: "move";
770 value "params" string: "next";
771 }
772 group "Elm_Config_Binding_Key" struct {
773 value "context" int: 0;
774 value "key" string: "KP_Next";
775 value "action" string: "move";
776 value "params" string: "next";
777 }
778 group "Elm_Config_Binding_Key" struct {
779 value "context" int: 0;
780 value "key" string: "Left";
781 value "action" string: "move";
782 value "params" string: "left";
783 }
784 group "Elm_Config_Binding_Key" struct {
785 value "context" int: 0;
786 value "key" string: "KP_Left";
787 value "action" string: "move";
788 value "params" string: "left";
789 }
790 group "Elm_Config_Binding_Key" struct {
791 value "context" int: 0;
792 value "key" string: "Right";
793 value "action" string: "move";
794 value "params" string: "right";
795 }
796 group "Elm_Config_Binding_Key" struct {
797 value "context" int: 0;
798 value "key" string: "KP_Right";
799 value "action" string: "move";
800 value "params" string: "right";
801 }
802 group "Elm_Config_Binding_Key" struct {
803 value "context" int: 0;
804 value "key" string: "Up";
805 value "action" string: "move";
806 value "params" string: "up";
807 }
808 group "Elm_Config_Binding_Key" struct {
809 value "context" int: 0;
810 value "key" string: "KP_Up";
811 value "action" string: "move";
812 value "params" string: "up";
813 }
814 group "Elm_Config_Binding_Key" struct {
815 value "context" int: 0;
816 value "key" string: "Down";
817 value "action" string: "move";
818 value "params" string: "down";
819 }
820 group "Elm_Config_Binding_Key" struct {
821 value "context" int: 0;
822 value "key" string: "KP_Down";
823 value "action" string: "move";
824 value "params" string: "down";
825 }
826 group "Elm_Config_Binding_Key" struct {
827 value "context" int: 0;
828 value "key" string: "Return";
829 value "action" string: "activate";
830 value "params" string: "";
831 }
832 group "Elm_Config_Binding_Key" struct {
833 value "context" int: 0;
834 value "key" string: "KP_Enter";
835 value "action" string: "activate";
836 value "params" string: "";
837 }
838 group "Elm_Config_Binding_Key" struct {
839 value "context" int: 0;
840 value "key" string: "space";
841 value "action" string: "activate";
842 value "params" string: "";
843 }
844 }
845 }
846 group "Elm_Config_Bindings_Widget" struct {
752 value "name" string: "Efl.Ui.Check"; 847 value "name" string: "Efl.Ui.Check";
753 group "key_bindings" list { 848 group "key_bindings" list {
754 group "Elm_Config_Binding_Key" struct { 849 group "Elm_Config_Binding_Key" struct {
diff --git a/config/mobile/base.src.in b/config/mobile/base.src.in
index abc3a3da0f..5f5b5dd63b 100644
--- a/config/mobile/base.src.in
+++ b/config/mobile/base.src.in
@@ -753,6 +753,101 @@ group "Elm_Config" struct {
753 } 753 }
754 } 754 }
755 group "Elm_Config_Bindings_Widget" struct { 755 group "Elm_Config_Bindings_Widget" struct {
756 value "name" string: "Efl.Ui.Calendar";
757 group "key_bindings" list {
758 group "Elm_Config_Binding_Key" struct {
759 value "context" int: 0;
760 value "key" string: "Prior";
761 value "action" string: "move";
762 value "params" string: "prior";
763 }
764 group "Elm_Config_Binding_Key" struct {
765 value "context" int: 0;
766 value "key" string: "KP_Prior";
767 value "action" string: "move";
768 value "params" string: "prior";
769 }
770 group "Elm_Config_Binding_Key" struct {
771 value "context" int: 0;
772 value "key" string: "Next";
773 value "action" string: "move";
774 value "params" string: "next";
775 }
776 group "Elm_Config_Binding_Key" struct {
777 value "context" int: 0;
778 value "key" string: "KP_Next";
779 value "action" string: "move";
780 value "params" string: "next";
781 }
782 group "Elm_Config_Binding_Key" struct {
783 value "context" int: 0;
784 value "key" string: "Left";
785 value "action" string: "move";
786 value "params" string: "left";
787 }
788 group "Elm_Config_Binding_Key" struct {
789 value "context" int: 0;
790 value "key" string: "KP_Left";
791 value "action" string: "move";
792 value "params" string: "left";
793 }
794 group "Elm_Config_Binding_Key" struct {
795 value "context" int: 0;
796 value "key" string: "Right";
797 value "action" string: "move";
798 value "params" string: "right";
799 }
800 group "Elm_Config_Binding_Key" struct {
801 value "context" int: 0;
802 value "key" string: "KP_Right";
803 value "action" string: "move";
804 value "params" string: "right";
805 }
806 group "Elm_Config_Binding_Key" struct {
807 value "context" int: 0;
808 value "key" string: "Up";
809 value "action" string: "move";
810 value "params" string: "up";
811 }
812 group "Elm_Config_Binding_Key" struct {
813 value "context" int: 0;
814 value "key" string: "KP_Up";
815 value "action" string: "move";
816 value "params" string: "up";
817 }
818 group "Elm_Config_Binding_Key" struct {
819 value "context" int: 0;
820 value "key" string: "Down";
821 value "action" string: "move";
822 value "params" string: "down";
823 }
824 group "Elm_Config_Binding_Key" struct {
825 value "context" int: 0;
826 value "key" string: "KP_Down";
827 value "action" string: "move";
828 value "params" string: "down";
829 }
830 group "Elm_Config_Binding_Key" struct {
831 value "context" int: 0;
832 value "key" string: "Return";
833 value "action" string: "activate";
834 value "params" string: "";
835 }
836 group "Elm_Config_Binding_Key" struct {
837 value "context" int: 0;
838 value "key" string: "KP_Enter";
839 value "action" string: "activate";
840 value "params" string: "";
841 }
842 group "Elm_Config_Binding_Key" struct {
843 value "context" int: 0;
844 value "key" string: "space";
845 value "action" string: "activate";
846 value "params" string: "";
847 }
848 }
849 }
850 group "Elm_Config_Bindings_Widget" struct {
756 value "name" string: "Efl.Ui.Check"; 851 value "name" string: "Efl.Ui.Check";
757 group "key_bindings" list { 852 group "key_bindings" list {
758 group "Elm_Config_Binding_Key" struct { 853 group "Elm_Config_Binding_Key" struct {
diff --git a/config/standard/base.src.in b/config/standard/base.src.in
index c3a3b223e4..13497910ae 100644
--- a/config/standard/base.src.in
+++ b/config/standard/base.src.in
@@ -750,6 +750,101 @@ group "Elm_Config" struct {
750 } 750 }
751 } 751 }
752 group "Elm_Config_Bindings_Widget" struct { 752 group "Elm_Config_Bindings_Widget" struct {
753 value "name" string: "Efl.Ui.Calendar";
754 group "key_bindings" list {
755 group "Elm_Config_Binding_Key" struct {
756 value "context" int: 0;
757 value "key" string: "Prior";
758 value "action" string: "move";
759 value "params" string: "prior";
760 }
761 group "Elm_Config_Binding_Key" struct {
762 value "context" int: 0;
763 value "key" string: "KP_Prior";
764 value "action" string: "move";
765 value "params" string: "prior";
766 }
767 group "Elm_Config_Binding_Key" struct {
768 value "context" int: 0;
769 value "key" string: "Next";
770 value "action" string: "move";
771 value "params" string: "next";
772 }
773 group "Elm_Config_Binding_Key" struct {
774 value "context" int: 0;
775 value "key" string: "KP_Next";
776 value "action" string: "move";
777 value "params" string: "next";
778 }
779 group "Elm_Config_Binding_Key" struct {
780 value "context" int: 0;
781 value "key" string: "Left";
782 value "action" string: "move";
783 value "params" string: "left";
784 }
785 group "Elm_Config_Binding_Key" struct {
786 value "context" int: 0;
787 value "key" string: "KP_Left";
788 value "action" string: "move";
789 value "params" string: "left";
790 }
791 group "Elm_Config_Binding_Key" struct {
792 value "context" int: 0;
793 value "key" string: "Right";
794 value "action" string: "move";
795 value "params" string: "right";
796 }
797 group "Elm_Config_Binding_Key" struct {
798 value "context" int: 0;
799 value "key" string: "KP_Right";
800 value "action" string: "move";
801 value "params" string: "right";
802 }
803 group "Elm_Config_Binding_Key" struct {
804 value "context" int: 0;
805 value "key" string: "Up";
806 value "action" string: "move";
807 value "params" string: "up";
808 }
809 group "Elm_Config_Binding_Key" struct {
810 value "context" int: 0;
811 value "key" string: "KP_Up";
812 value "action" string: "move";
813 value "params" string: "up";
814 }
815 group "Elm_Config_Binding_Key" struct {
816 value "context" int: 0;
817 value "key" string: "Down";
818 value "action" string: "move";
819 value "params" string: "down";
820 }
821 group "Elm_Config_Binding_Key" struct {
822 value "context" int: 0;
823 value "key" string: "KP_Down";
824 value "action" string: "move";
825 value "params" string: "down";
826 }
827 group "Elm_Config_Binding_Key" struct {
828 value "context" int: 0;
829 value "key" string: "Return";
830 value "action" string: "activate";
831 value "params" string: "";
832 }
833 group "Elm_Config_Binding_Key" struct {
834 value "context" int: 0;
835 value "key" string: "KP_Enter";
836 value "action" string: "activate";
837 value "params" string: "";
838 }
839 group "Elm_Config_Binding_Key" struct {
840 value "context" int: 0;
841 value "key" string: "space";
842 value "action" string: "activate";
843 value "params" string: "";
844 }
845 }
846 }
847 group "Elm_Config_Bindings_Widget" struct {
753 value "name" string: "Efl.Ui.Check"; 848 value "name" string: "Efl.Ui.Check";
754 group "key_bindings" list { 849 group "key_bindings" list {
755 group "Elm_Config_Binding_Key" struct { 850 group "Elm_Config_Binding_Key" struct {
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 27588cc07e..06b1e60a02 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -108,6 +108,7 @@ src/lib/elementary/elm_box.c
108src/lib/elementary/elm_bubble.c 108src/lib/elementary/elm_bubble.c
109src/lib/elementary/efl_ui_button.c 109src/lib/elementary/efl_ui_button.c
110src/lib/elementary/elm_calendar.c 110src/lib/elementary/elm_calendar.c
111src/lib/elementary/efl_ui_calendar.c
111src/lib/elementary/efl_ui_check.c 112src/lib/elementary/efl_ui_check.c
112src/lib/elementary/elm_clock.c 113src/lib/elementary/elm_clock.c
113src/lib/elementary/elm_cnp.c 114src/lib/elementary/elm_cnp.c
diff --git a/src/Makefile_Elementary.am b/src/Makefile_Elementary.am
index e9c10db80a..b83482e047 100644
--- a/src/Makefile_Elementary.am
+++ b/src/Makefile_Elementary.am
@@ -7,6 +7,7 @@ elm_public_eolian_files = \
7 lib/elementary/efl_ui_bg.eo \ 7 lib/elementary/efl_ui_bg.eo \
8 lib/elementary/efl_ui_button.eo \ 8 lib/elementary/efl_ui_button.eo \
9 lib/elementary/elm_calendar.eo \ 9 lib/elementary/elm_calendar.eo \
10 lib/elementary/efl_ui_calendar.eo \
10 lib/elementary/efl_ui_check.eo \ 11 lib/elementary/efl_ui_check.eo \
11 lib/elementary/elm_clock.eo \ 12 lib/elementary/elm_clock.eo \
12 lib/elementary/elm_colorselector.eo \ 13 lib/elementary/elm_colorselector.eo \
@@ -247,6 +248,7 @@ includesunstable_HEADERS = \
247 lib/elementary/efl_ui_button_private.h \ 248 lib/elementary/efl_ui_button_private.h \
248 lib/elementary/efl_ui_bg_private.h \ 249 lib/elementary/efl_ui_bg_private.h \
249 lib/elementary/elm_widget_calendar.h \ 250 lib/elementary/elm_widget_calendar.h \
251 lib/elementary/efl_ui_calendar_private.h \
250 lib/elementary/efl_ui_check_private.h \ 252 lib/elementary/efl_ui_check_private.h \
251 lib/elementary/elm_widget_clock.h \ 253 lib/elementary/elm_widget_clock.h \
252 lib/elementary/elm_widget_colorselector.h \ 254 lib/elementary/elm_widget_colorselector.h \
@@ -370,6 +372,8 @@ includesub_HEADERS = \
370 lib/elementary/elm_calendar_eo.h \ 372 lib/elementary/elm_calendar_eo.h \
371 lib/elementary/elm_calendar_legacy.h \ 373 lib/elementary/elm_calendar_legacy.h \
372 lib/elementary/elm_calendar_common.h \ 374 lib/elementary/elm_calendar_common.h \
375 lib/elementary/efl_ui_calendar.h \
376 lib/elementary/efl_ui_calendar_common.h \
373 lib/elementary/elm_check.h \ 377 lib/elementary/elm_check.h \
374 lib/elementary/efl_ui_check_eo.h \ 378 lib/elementary/efl_ui_check_eo.h \
375 lib/elementary/elm_check_legacy.h \ 379 lib/elementary/elm_check_legacy.h \
@@ -584,6 +588,7 @@ lib_elementary_libelementary_la_SOURCES = \
584 lib/elementary/elm_bubble.c \ 588 lib/elementary/elm_bubble.c \
585 lib/elementary/efl_ui_button.c \ 589 lib/elementary/efl_ui_button.c \
586 lib/elementary/elm_calendar.c \ 590 lib/elementary/elm_calendar.c \
591 lib/elementary/efl_ui_calendar.c \
587 lib/elementary/efl_ui_check.c \ 592 lib/elementary/efl_ui_check.c \
588 lib/elementary/elm_clock.c \ 593 lib/elementary/elm_clock.c \
589 lib/elementary/elm_cnp.c \ 594 lib/elementary/elm_cnp.c \
diff --git a/src/bin/elementary/test.c b/src/bin/elementary/test.c
index 2abfdf8799..14fa889a66 100644
--- a/src/bin/elementary/test.c
+++ b/src/bin/elementary/test.c
@@ -200,6 +200,7 @@ void test_panes_minsize(void *data, Evas_Object *obj, void *event_info);
200void test_calendar(void *data, Evas_Object *obj, void *event_info); 200void test_calendar(void *data, Evas_Object *obj, void *event_info);
201void test_calendar2(void *data, Evas_Object *obj, void *event_info); 201void test_calendar2(void *data, Evas_Object *obj, void *event_info);
202void test_calendar3(void *data, Evas_Object *obj, void *event_info); 202void test_calendar3(void *data, Evas_Object *obj, void *event_info);
203void test_efl_ui_calendar(void *data, Evas_Object *obj, void *event_info);
203void test_map(void *data, Evas_Object *obj, void *event_info); 204void test_map(void *data, Evas_Object *obj, void *event_info);
204void test_weather(void *data, Evas_Object *obj, void *event_info); 205void test_weather(void *data, Evas_Object *obj, void *event_info);
205void test_flip(void *data, Evas_Object *obj, void *event_info); 206void test_flip(void *data, Evas_Object *obj, void *event_info);
@@ -1002,6 +1003,7 @@ add_tests:
1002 ADD_TEST(NULL, "Times & Dates", "Calendar", test_calendar); 1003 ADD_TEST(NULL, "Times & Dates", "Calendar", test_calendar);
1003 ADD_TEST(NULL, "Times & Dates", "Calendar 2", test_calendar2); 1004 ADD_TEST(NULL, "Times & Dates", "Calendar 2", test_calendar2);
1004 ADD_TEST(NULL, "Times & Dates", "Calendar 3", test_calendar3); 1005 ADD_TEST(NULL, "Times & Dates", "Calendar 3", test_calendar3);
1006 ADD_TEST(NULL, "Times & Dates", "Efl Ui Calendar", test_efl_ui_calendar);
1005 ADD_TEST(NULL, "Times & Dates", "Clock", test_clock); 1007 ADD_TEST(NULL, "Times & Dates", "Clock", test_clock);
1006 ADD_TEST(NULL, "Times & Dates", "Clock Edit", test_clock_edit); 1008 ADD_TEST(NULL, "Times & Dates", "Clock Edit", test_clock_edit);
1007 ADD_TEST(NULL, "Times & Dates", "Clock Edit 2", test_clock_edit2); 1009 ADD_TEST(NULL, "Times & Dates", "Clock Edit 2", test_clock_edit2);
diff --git a/src/bin/elementary/test_calendar.c b/src/bin/elementary/test_calendar.c
index 35e1bf95a6..2bcfc17657 100644
--- a/src/bin/elementary/test_calendar.c
+++ b/src/bin/elementary/test_calendar.c
@@ -379,3 +379,59 @@ test_calendar3(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event
379 379
380 evas_object_show(win); 380 evas_object_show(win);
381} 381}
382
383static void
384_cal_changed_cb(void *data EINA_UNUSED, const Efl_Event *ev)
385{
386 struct tm selected_date;
387 struct tm max_date;
388 struct tm min_date;
389
390 selected_date = efl_ui_calendar_date_get(ev->object);
391 min_date = efl_ui_calendar_date_min_get(ev->object);
392 max_date = efl_ui_calendar_date_max_get(ev->object);
393 printf("Selected Date is %i/%i/%i\n",
394 selected_date.tm_mday,
395 selected_date.tm_mon + 1,
396 selected_date.tm_year + 1900);
397 printf("Minimum Date is %i/%i/%i\n",
398 min_date.tm_mday,
399 min_date.tm_mon + 1,
400 min_date.tm_year + 1900);
401 printf("Max Date is %i/%i/%i\n",
402 max_date.tm_mday,
403 max_date.tm_mon + 1,
404 max_date.tm_year + 1900);
405}
406
407void
408test_efl_ui_calendar(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
409{
410 Evas_Object *win, *box;
411 struct tm selected_date, min_date, max_date;
412 time_t current_date;
413
414 current_date = time(NULL) + SEC_PER_DAY;
415 localtime_r(&current_date, &selected_date);
416 current_date = time(NULL) - SEC_PER_YEAR;
417 localtime_r(&current_date, &min_date);
418 current_date = time(NULL) + SEC_PER_YEAR;
419 localtime_r(&current_date, &max_date);
420
421 win = efl_add(EFL_UI_WIN_CLASS, NULL,
422 efl_text_set(efl_added, "Efl Ui Calendar"),
423 efl_ui_win_autodel_set(efl_added, EINA_TRUE));
424
425 box = efl_add(EFL_UI_BOX_CLASS, win,
426 efl_ui_direction_set(efl_added, EFL_UI_DIR_HORIZONTAL),
427 efl_content_set(win, efl_added));
428
429 efl_add(EFL_UI_CALENDAR_CLASS, win,
430 efl_ui_calendar_date_set(efl_added, selected_date),
431 efl_ui_calendar_date_min_set(efl_added, min_date),
432 efl_ui_calendar_date_max_set(efl_added, max_date),
433 efl_event_callback_add(efl_added, EFL_UI_CALENDAR_EVENT_CHANGED, _cal_changed_cb, NULL),
434 efl_pack(box, efl_added));
435
436 efl_gfx_size_set(win, EINA_SIZE2D(300, 300));
437}
diff --git a/src/lib/elementary/Elementary.h b/src/lib/elementary/Elementary.h
index c1065ec754..4d22b69b83 100644
--- a/src/lib/elementary/Elementary.h
+++ b/src/lib/elementary/Elementary.h
@@ -197,6 +197,7 @@ EAPI extern Elm_Version *elm_version;
197#include <elm_button.h> 197#include <elm_button.h>
198#include <elm_cache.h> 198#include <elm_cache.h>
199#include <elm_calendar.h> 199#include <elm_calendar.h>
200#include <efl_ui_calendar.h>
200#include <elm_check.h> 201#include <elm_check.h>
201#include <elm_clock.h> 202#include <elm_clock.h>
202#include <elm_cnp.h> 203#include <elm_cnp.h>
diff --git a/src/lib/elementary/efl_ui_calendar.c b/src/lib/elementary/efl_ui_calendar.c
new file mode 100644
index 0000000000..66ca500bd4
--- /dev/null
+++ b/src/lib/elementary/efl_ui_calendar.c
@@ -0,0 +1,1214 @@
1#ifdef HAVE_CONFIG_H
2# include "elementary_config.h"
3#endif
4
5#define ELM_INTERFACE_ATSPI_ACCESSIBLE_PROTECTED
6#define ELM_INTERFACE_ATSPI_WIDGET_ACTION_PROTECTED
7
8#include <Elementary.h>
9#include "elm_priv.h"
10#include "efl_ui_calendar_private.h"
11
12#define MY_CLASS EFL_UI_CALENDAR_CLASS
13
14#define MY_CLASS_NAME "Efl.Ui.Calendar"
15#define MY_CLASS_PFX efl_ui_calendar
16
17#define EFL_UI_CALENDAR_BUTTON_LEFT "elm,calendar,button,left"
18#define EFL_UI_CALENDAR_BUTTON_RIGHT "elm,calendar,button,right"
19#define EFL_UI_CALENDAR_BUTTON_YEAR_LEFT "elm,calendar,button_year,left"
20#define EFL_UI_CALENDAR_BUTTON_YEAR_RIGHT "elm,calendar,button_year,right"
21
22static const char SIG_CHANGED[] = "changed";
23
24static const Evas_Smart_Cb_Description _smart_callbacks[] = {
25 {SIG_CHANGED, ""},
26 {SIG_WIDGET_LANG_CHANGED, ""}, /**< handled by elm_widget */
27 {SIG_WIDGET_ACCESS_CHANGED, ""}, /**< handled by elm_widget */
28 {SIG_LAYOUT_FOCUSED, ""}, /**< handled by elm_layout */
29 {SIG_LAYOUT_UNFOCUSED, ""}, /**< handled by elm_layout */
30 {NULL, NULL}
31};
32
33static void
34_button_widget_month_inc_start_click(void *data,
35 Evas_Object *obj EINA_UNUSED,
36 void *event_info EINA_UNUSED);
37static void
38_button_widget_month_inc_start(void *data,
39 Evas_Object *obj EINA_UNUSED,
40 void *event_info EINA_UNUSED);
41static void
42_button_widget_month_dec_start_click(void *data,
43 Evas_Object *obj EINA_UNUSED,
44 void *event_info EINA_UNUSED);
45static void
46_button_widget_month_dec_start(void *data,
47 Evas_Object *obj EINA_UNUSED,
48 void *event_info EINA_UNUSED);
49
50static Eina_Bool _key_action_activate(Evas_Object *obj, const char *params);
51
52static const Elm_Action key_actions[] = {
53 {"activate", _key_action_activate},
54 {NULL, NULL}
55};
56
57/* Should not be translated, it's used if we failed
58 * getting from locale. */
59static const char *_days_abbrev[] =
60{
61 "Sun", "Mon", "Tue", "Wed",
62 "Thu", "Fri", "Sat"
63};
64
65static int _days_in_month[2][12] =
66{
67 {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
68 {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
69};
70
71static Eina_Bool _efl_ui_calendar_smart_focus_next_enable = EINA_FALSE;
72
73EOLIAN static void
74_efl_ui_calendar_elm_layout_sizing_eval(Eo *obj, Efl_Ui_Calendar_Data *_pd EINA_UNUSED)
75{
76 Evas_Coord minw = -1, minh = -1;
77 EFL_UI_CALENDAR_DATA_GET(obj, sd);
78 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
79
80 if (sd->filling) return;
81 // 7x8 (1 month+year, days, 6 dates.)
82 elm_coords_finger_size_adjust(7, &minw, 8, &minh);
83 edje_object_size_min_restricted_calc
84 (wd->resize_obj, &minw, &minh, minw, minh);
85 evas_object_size_hint_min_set(obj, minw, minh);
86 evas_object_size_hint_max_set(obj, -1, -1);
87}
88
89// Get the max day number for each month
90static inline int
91_maxdays_get(struct tm *date, int month_offset)
92{
93 int month, year;
94
95 month = (date->tm_mon + month_offset) % 12;
96 year = date->tm_year + 1900;
97
98 if (month < 0) month += 12;
99
100 return _days_in_month
101 [((!(year % 4)) && ((!(year % 400)) || (year % 100)))][month];
102}
103
104static inline void
105_unselect(Evas_Object *obj,
106 int selected)
107{
108 char emission[32];
109
110 snprintf(emission, sizeof(emission), "cit_%d,unselected", selected);
111 elm_layout_signal_emit(obj, emission, "elm");
112}
113
114static inline void
115_select(Evas_Object *obj,
116 int selected)
117{
118 char emission[32];
119
120 EFL_UI_CALENDAR_DATA_GET(obj, sd);
121
122 sd->focused_it = sd->selected_it = selected;
123 snprintf(emission, sizeof(emission), "cit_%d,selected", selected);
124 elm_layout_signal_emit(obj, emission, "elm");
125}
126
127static inline void
128_not_today(Efl_Ui_Calendar_Data *sd)
129{
130 char emission[32];
131
132 snprintf(emission, sizeof(emission), "cit_%d,not_today", sd->today_it);
133 elm_layout_signal_emit(sd->obj, emission, "elm");
134 sd->today_it = -1;
135}
136
137static inline void
138_today(Efl_Ui_Calendar_Data *sd,
139 int it)
140{
141 char emission[32];
142
143 snprintf(emission, sizeof(emission), "cit_%d,today", it);
144 elm_layout_signal_emit(sd->obj, emission, "elm");
145 sd->today_it = it;
146}
147
148static inline void
149_enable(Efl_Ui_Calendar_Data *sd,
150 int it)
151{
152 char emission[32];
153
154 snprintf(emission, sizeof(emission), "cit_%d,enable", it);
155 elm_layout_signal_emit(sd->obj, emission, "elm");
156}
157
158static inline void
159_disable(Efl_Ui_Calendar_Data *sd,
160 int it)
161{
162 char emission[32];
163
164 snprintf(emission, sizeof(emission), "cit_%d,disable", it);
165 elm_layout_signal_emit(sd->obj, emission, "elm");
166}
167
168static char *
169_format_month_year(struct tm *date)
170{
171 return eina_strftime(E_("%B %Y"), date);
172}
173
174static void
175_set_month_year(Efl_Ui_Calendar_Data *sd)
176{
177 char *buf;
178
179 sd->filling = EINA_TRUE;
180
181 buf = sd->format_func(&sd->shown_date);
182
183 if (buf)
184 {
185 elm_layout_text_set(sd->obj, "month_text", buf);
186 free(buf);
187 }
188 else elm_layout_text_set(sd->obj, "month_text", "");
189
190 sd->filling = EINA_FALSE;
191}
192
193static char *
194_access_info_cb(void *data EINA_UNUSED, Evas_Object *obj)
195{
196 char *ret;
197 Eina_Strbuf *buf;
198 buf = eina_strbuf_new();
199
200 eina_strbuf_append_printf(buf, "day %s", elm_widget_access_info_get(obj));
201
202 ret = eina_strbuf_string_steal(buf);
203 eina_strbuf_free(buf);
204 return ret;
205}
206
207static void
208_access_calendar_item_register(Evas_Object *obj)
209{
210 unsigned int maxdays, i;
211 char day_s[13], pname[14];
212 unsigned day = 0;
213 Evas_Object *ao;
214
215 EFL_UI_CALENDAR_DATA_GET(obj, sd);
216
217 maxdays = _maxdays_get(&sd->shown_date, 0);
218 for (i = 0; i < 42; i++)
219 {
220 if ((!day) && (i == sd->first_day_it)) day = 1;
221 if ((day) && (day <= maxdays))
222 {
223 snprintf(pname, sizeof(pname), "cit_%d.access", i);
224
225 ao = _elm_access_edje_object_part_object_register
226 (obj, elm_layout_edje_get(obj), pname);
227 _elm_access_text_set(_elm_access_info_get(ao),
228 ELM_ACCESS_TYPE, E_("calendar item"));
229 _elm_access_callback_set(_elm_access_info_get(ao),
230 ELM_ACCESS_INFO, _access_info_cb, NULL);
231
232 snprintf(day_s, sizeof(day_s), "%d", (int) (day++));
233 elm_widget_access_info_set(ao, (const char*)day_s);
234 }
235 else
236 {
237 snprintf(pname, sizeof(pname), "cit_%d.access", i);
238 _elm_access_edje_object_part_object_unregister
239 (obj, elm_layout_edje_get(obj), pname);
240 }
241 }
242}
243
244static void
245_access_calendar_spinner_register(Evas_Object *obj)
246{
247 Evas_Object *po;
248 Elm_Access_Info *ai;
249 EFL_UI_CALENDAR_DATA_GET(obj, sd);
250
251 if (!sd->dec_btn_month)
252 sd->dec_btn_month = _elm_access_edje_object_part_object_register
253 (obj, elm_layout_edje_get(obj), "left_bt");
254 ai = _elm_access_info_get(sd->dec_btn_month);
255 _elm_access_text_set(ai, ELM_ACCESS_TYPE, E_("calendar decrement month button"));
256
257 if (!sd->inc_btn_month)
258 sd->inc_btn_month = _elm_access_edje_object_part_object_register
259 (obj, elm_layout_edje_get(obj), "right_bt");
260 ai = _elm_access_info_get(sd->inc_btn_month);
261 _elm_access_text_set(ai, ELM_ACCESS_TYPE, E_("calendar increment month button"));
262
263 sd->month_access = _elm_access_edje_object_part_object_register
264 (obj, elm_layout_edje_get(obj), "text_month");
265 ai = _elm_access_info_get(sd->month_access);
266 _elm_access_text_set(ai, ELM_ACCESS_TYPE, E_("calendar month"));
267
268 ai = _elm_access_info_get(sd->year_access);
269 _elm_access_text_set(ai, ELM_ACCESS_TYPE, E_("calendar year"));
270
271 po = (Evas_Object *)edje_object_part_object_get
272 (elm_layout_edje_get(obj), "month_text");
273 evas_object_pass_events_set(po, EINA_FALSE);
274}
275
276static void
277_access_calendar_register(Evas_Object *obj)
278{
279 _access_calendar_spinner_register(obj);
280 _access_calendar_item_register(obj);
281}
282
283static void
284_populate(Evas_Object *obj)
285{
286 int maxdays, prev_month_maxdays, day, mon, yr, i;
287 char part[12], day_s[3];
288 struct tm first_day;
289
290 EFL_UI_CALENDAR_DATA_GET(obj, sd);
291
292 elm_layout_freeze(obj);
293
294 sd->filling = EINA_FALSE;
295 if (sd->today_it > 0) _not_today(sd);
296
297 maxdays = _maxdays_get(&sd->shown_date, 0);
298 prev_month_maxdays = _maxdays_get(&sd->shown_date, -1);
299 mon = sd->shown_date.tm_mon;
300 yr = sd->shown_date.tm_year;
301
302 _set_month_year(sd);
303 sd->filling = EINA_TRUE;
304
305 /* Set days */
306 day = 0;
307 first_day = sd->shown_date;
308 first_day.tm_mday = 1;
309 if (mktime(&first_day) == -1)
310 {
311 ERR("mktime can not give week day for this month properly. Please check year or month is proper.");
312 return;
313 }
314
315 // Layout of the calendar is changed for removing the unfilled last row.
316 if (first_day.tm_wday < (int)sd->first_week_day)
317 sd->first_day_it = first_day.tm_wday + ELM_DAY_LAST - sd->first_week_day;
318 else
319 sd->first_day_it = first_day.tm_wday - sd->first_week_day;
320
321 for (i = 0; i < 42; i++)
322 {
323 if ((!day) && (i == sd->first_day_it)) day = 1;
324
325 if ((day == sd->current_date.tm_mday)
326 && (mon == sd->current_date.tm_mon)
327 && (yr == sd->current_date.tm_year))
328 _today(sd, i);
329
330 if (day == sd->date.tm_mday)
331 {
332 if ((sd->selected_it > -1) && (sd->selected_it != i))
333 _unselect(obj, sd->selected_it);
334
335 if ((mon == sd->date.tm_mon) && (yr == sd->date.tm_year))
336 _select(obj, i);
337 }
338
339 if ((day) && (day <= maxdays))
340 {
341 if (((yr == sd->date_min.tm_year) && (mon == sd->date_min.tm_mon) && (day < sd->date_min.tm_mday))
342 || ((yr == sd->date_max.tm_year) && (mon == sd->date_max.tm_mon) && (day > sd->date_max.tm_mday)))
343 _disable(sd, i);
344 else
345 _enable(sd, i);
346
347 snprintf(day_s, sizeof(day_s), "%d", day++);
348 }
349 else
350 {
351 _disable(sd, i);
352
353 if (day <= maxdays)
354 snprintf(day_s, sizeof(day_s), "%d", prev_month_maxdays - sd->first_day_it + i + 1);
355 else
356 snprintf(day_s, sizeof(day_s), "%d", i - sd->first_day_it - maxdays + 1);
357 }
358
359 snprintf(part, sizeof(part), "cit_%d.text", i);
360 elm_layout_text_set(obj, part, day_s);
361 }
362
363 // ACCESS
364 if ((_elm_config->access_mode != ELM_ACCESS_MODE_OFF))
365 _access_calendar_item_register(obj);
366
367 sd->filling = EINA_FALSE;
368
369 elm_layout_thaw(obj);
370 edje_object_message_signal_process(elm_layout_edje_get(obj));
371}
372
373static void
374_set_headers(Evas_Object *obj)
375{
376 static char part[] = "ch_0.text";
377 int i;
378 struct tm *t;
379 time_t temp = 259200; // the first sunday since epoch
380 EFL_UI_CALENDAR_DATA_GET(obj, sd);
381
382 elm_layout_freeze(obj);
383
384 sd->filling = EINA_TRUE;
385
386 t = gmtime(&temp);
387 if (t)
388 {
389 t->tm_wday = 0;
390 for (i = 0; i < ELM_DAY_LAST; i++)
391 {
392 char *buf;
393 buf = eina_strftime("%a", t);
394 if (buf)
395 {
396 sd->weekdays[i] = eina_stringshare_add(buf);
397 free(buf);
398 }
399 else
400 {
401 /* If we failed getting day, get a default value */
402 sd->weekdays[i] = _days_abbrev[i];
403 WRN("Failed getting weekday name for '%s' from locale.",
404 _days_abbrev[i]);
405 }
406 t->tm_wday++;
407 }
408 }
409
410 for (i = 0; i < ELM_DAY_LAST; i++)
411 {
412 part[3] = i + '0';
413 elm_layout_text_set(obj, part, sd->weekdays[(i + sd->first_week_day) % ELM_DAY_LAST]);
414 }
415
416 sd->filling = EINA_FALSE;
417
418 elm_layout_thaw(obj);
419}
420
421static void
422_spinner_buttons_add(Evas_Object *obj, Efl_Ui_Calendar_Data *sd)
423{
424 char left_buf[255] = { 0 };
425 char right_buf[255] = { 0 };
426
427 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
428
429 snprintf(left_buf, sizeof(left_buf), "calendar/decrease/%s", elm_object_style_get(obj));
430 snprintf(right_buf, sizeof(right_buf), "calendar/increase/%s", elm_object_style_get(obj));
431
432 if (edje_object_part_exists(wd->resize_obj, EFL_UI_CALENDAR_BUTTON_LEFT))
433 {
434 if (sd->dec_btn_month && efl_isa(sd->dec_btn_month, ELM_ACCESS_CLASS))
435 {
436 _elm_access_edje_object_part_object_unregister
437 (obj, elm_layout_edje_get(obj), "left_bt");
438 sd->dec_btn_month = NULL;
439 }
440
441 if (!sd->dec_btn_month)
442 {
443 sd->dec_btn_month = elm_button_add(obj);
444 elm_button_autorepeat_set(sd->dec_btn_month, EINA_TRUE);
445 elm_button_autorepeat_initial_timeout_set(sd->dec_btn_month, 0.5);
446 elm_button_autorepeat_gap_timeout_set(sd->dec_btn_month, 0.2);
447 evas_object_smart_callback_add(sd->dec_btn_month, "clicked", _button_widget_month_dec_start_click, obj);
448 evas_object_smart_callback_add(sd->dec_btn_month, "repeated", _button_widget_month_dec_start, obj);
449 }
450
451 elm_object_style_set(sd->dec_btn_month, left_buf);
452 elm_layout_content_set(obj, EFL_UI_CALENDAR_BUTTON_LEFT, sd->dec_btn_month);
453 }
454 else if (sd->dec_btn_month && !efl_isa(sd->dec_btn_month, ELM_ACCESS_CLASS))
455 {
456 evas_object_del(sd->dec_btn_month);
457 sd->dec_btn_month = NULL;
458 }
459
460 if (edje_object_part_exists(wd->resize_obj, EFL_UI_CALENDAR_BUTTON_RIGHT))
461 {
462 if (sd->inc_btn_month && efl_isa(sd->inc_btn_month, ELM_ACCESS_CLASS))
463 {
464 _elm_access_edje_object_part_object_unregister
465 (obj, elm_layout_edje_get(obj), "right_bt");
466 sd->inc_btn_month = NULL;
467 }
468
469 if (!sd->inc_btn_month)
470 {
471 sd->inc_btn_month = elm_button_add(obj);
472 elm_button_autorepeat_set(sd->inc_btn_month, EINA_TRUE);
473 elm_button_autorepeat_initial_timeout_set(sd->inc_btn_month, 0.5);
474 elm_button_autorepeat_gap_timeout_set(sd->inc_btn_month, 0.2);
475 evas_object_smart_callback_add(sd->inc_btn_month, "clicked", _button_widget_month_inc_start_click, obj);
476 evas_object_smart_callback_add(sd->inc_btn_month, "repeated", _button_widget_month_inc_start, obj);
477 }
478
479 elm_object_style_set(sd->inc_btn_month, right_buf);
480 elm_layout_content_set(obj, EFL_UI_CALENDAR_BUTTON_RIGHT, sd->inc_btn_month);
481 }
482 else if (sd->inc_btn_month && !efl_isa(sd->inc_btn_month, ELM_ACCESS_CLASS))
483 {
484 evas_object_del(sd->inc_btn_month);
485 sd->inc_btn_month = NULL;
486 }
487}
488
489EOLIAN static Efl_Ui_Theme_Apply
490_efl_ui_calendar_elm_widget_theme_apply(Eo *obj, Efl_Ui_Calendar_Data *sd)
491{
492 Efl_Ui_Theme_Apply int_ret = EFL_UI_THEME_APPLY_FAILED;
493
494 int_ret = efl_ui_widget_theme_apply(efl_super(obj, MY_CLASS));
495 if (!int_ret) return EFL_UI_THEME_APPLY_FAILED;
496
497 _spinner_buttons_add(obj, sd);
498
499 evas_object_smart_changed(obj);
500 return int_ret;
501}
502
503/* Set correct tm_wday and tm_yday after other fields changes*/
504static inline Eina_Bool
505_fix_date(Efl_Ui_Calendar_Data *sd)
506{
507 Eina_Bool fixed = EINA_FALSE;
508
509 if ((sd->date.tm_year < sd->date_min.tm_year) ||
510 ((sd->date.tm_year == sd->date_min.tm_year) &&
511 (sd->date.tm_mon < sd->date_min.tm_mon)) ||
512 ((sd->date.tm_year == sd->date_min.tm_year) &&
513 (sd->date.tm_mon == sd->date_min.tm_mon) &&
514 (sd->date.tm_mday < sd->date_min.tm_mday)))
515 {
516 sd->date.tm_year = sd->shown_date.tm_year = sd->date_min.tm_year;
517 sd->date.tm_mon = sd->shown_date.tm_mon = sd->date_min.tm_mon;
518 sd->date.tm_mday = sd->shown_date.tm_mday = sd->date_min.tm_mday;
519 fixed = EINA_TRUE;
520 }
521 else if ((sd->date_max.tm_year != -1) &&
522 ((sd->date.tm_year > sd->date_max.tm_year) ||
523 ((sd->date.tm_year == sd->date_max.tm_year) &&
524 (sd->date.tm_mon > sd->date_max.tm_mon)) ||
525 ((sd->date.tm_year == sd->date_max.tm_year) &&
526 (sd->date.tm_mon == sd->date_max.tm_mon) &&
527 (sd->date.tm_mday > sd->date_max.tm_mday))))
528 {
529 sd->date.tm_year = sd->shown_date.tm_year = sd->date_max.tm_year;
530 sd->date.tm_mon = sd->shown_date.tm_mon = sd->date_max.tm_mon;
531 sd->date.tm_mday = sd->shown_date.tm_mday = sd->date_max.tm_mday;
532 fixed = EINA_TRUE;
533 }
534 else
535 {
536 if (sd->date.tm_mon != sd->shown_date.tm_mon)
537 sd->date.tm_mon = sd->shown_date.tm_mon;
538 if (sd->date.tm_year != sd->shown_date.tm_year)
539 sd->date.tm_year = sd->shown_date.tm_year;
540 }
541
542 return fixed;
543}
544
545static Eina_Bool
546_update_data(Evas_Object *obj, int delta)
547{
548 struct tm time_check;
549 int maxdays;
550
551 EFL_UI_CALENDAR_DATA_GET(obj, sd);
552
553 /* check if it's a valid time. for 32 bits, year greater than 2037 is not */
554 time_check = sd->shown_date;
555 time_check.tm_mon += delta;
556
557 if (mktime(&time_check) == -1)
558 {
559 ERR("mktime can not give week day for the next month. Please check what is wrong with udpate date.");
560 return EINA_FALSE;
561 }
562
563 sd->shown_date.tm_mon += delta;
564
565 if (delta < 0)
566 {
567 if (sd->shown_date.tm_year == sd->date_min.tm_year)
568 {
569 if (sd->shown_date.tm_mon < sd->date_min.tm_mon)
570 {
571 sd->shown_date.tm_mon = sd->date_min.tm_mon;
572 return EINA_FALSE;
573 }
574 }
575 else if (sd->shown_date.tm_mon < 0)
576 {
577 sd->shown_date.tm_mon = 11;
578 sd->shown_date.tm_year--;
579 }
580 }
581 else
582 {
583 if (sd->shown_date.tm_year == sd->date_max.tm_year)
584 {
585 if (sd->shown_date.tm_mon > sd->date_max.tm_mon)
586 {
587 sd->shown_date.tm_mon = sd->date_max.tm_mon;
588 return EINA_FALSE;
589 }
590 }
591 else if (sd->shown_date.tm_mon > 11)
592 {
593 sd->shown_date.tm_mon = 0;
594 sd->shown_date.tm_year++;
595 }
596 }
597
598 maxdays = _maxdays_get(&sd->shown_date, 0);
599 if (sd->date.tm_mday > maxdays)
600 sd->date.tm_mday = maxdays;
601
602 return EINA_TRUE;
603}
604
605static Eina_Bool
606_spin_month_value(void *data)
607{
608 EFL_UI_CALENDAR_DATA_GET(data, sd);
609
610 if (_update_data(data, sd->spin_speed))
611 evas_object_smart_changed(data);
612
613 sd->interval = sd->interval / 1.05;
614 ecore_timer_interval_set(sd->spin_month, sd->interval);
615
616 return ECORE_CALLBACK_RENEW;
617}
618
619static void
620_button_widget_month_inc_start_click(void *data,
621 Evas_Object *obj EINA_UNUSED,
622 void *event_info EINA_UNUSED)
623{
624 EFL_UI_CALENDAR_DATA_GET(data, sd);
625 if (sd->month_repeated)
626 {
627 sd->month_repeated = EINA_FALSE;
628 return;
629 }
630
631 sd->interval = sd->first_interval;
632 sd->spin_speed = 1;
633 _spin_month_value(data);
634}
635
636static void
637_button_widget_month_inc_start(void *data,
638 Evas_Object *obj EINA_UNUSED,
639 void *event_info EINA_UNUSED)
640{
641 EFL_UI_CALENDAR_DATA_GET(data, sd);
642
643 sd->spin_speed = 1;
644 if (!sd->month_repeated)
645 sd->interval = sd->first_interval;
646 sd->month_repeated = EINA_TRUE;
647 _spin_month_value(data);
648
649}
650
651static void
652_button_widget_month_dec_start_click(void *data,
653 Evas_Object *obj EINA_UNUSED,
654 void *event_info EINA_UNUSED)
655{
656 EFL_UI_CALENDAR_DATA_GET(data, sd);
657 if (sd->month_repeated)
658 {
659 sd->month_repeated = EINA_FALSE;
660 return;
661 }
662
663 sd->interval = sd->first_interval;
664 sd->spin_speed = -1;
665 _spin_month_value(data);
666}
667
668static void
669_button_widget_month_dec_start(void *data,
670 Evas_Object *obj EINA_UNUSED,
671 void *event_info EINA_UNUSED)
672{
673 EFL_UI_CALENDAR_DATA_GET(data, sd);
674
675 sd->spin_speed = -1;
676 if (!sd->month_repeated)
677 sd->interval = sd->first_interval;
678 sd->month_repeated = EINA_TRUE;
679 _spin_month_value(data);
680}
681
682static int
683_get_item_day(Evas_Object *obj,
684 int selected_it)
685{
686 int day;
687
688 EFL_UI_CALENDAR_DATA_GET(obj, sd);
689
690 day = selected_it - sd->first_day_it + 1;
691 if ((day < 0) || (day > _maxdays_get(&sd->shown_date, 0)))
692 return 0;
693
694 if ((sd->shown_date.tm_year == sd->date_min.tm_year)
695 && (sd->shown_date.tm_mon == sd->date_min.tm_mon)
696 && (day < sd->date_min.tm_mday))
697 {
698 return 0;
699 }
700 else if ((sd->shown_date.tm_year == sd->date_max.tm_year)
701 && (sd->shown_date.tm_mon == sd->date_max.tm_mon)
702 && (day > sd->date_max.tm_mday))
703 {
704 return 0;
705 }
706
707 return day;
708}
709
710static void
711_update_unfocused_it(Evas_Object *obj, int unfocused_it)
712{
713 int day;
714 char emission[32];
715
716 EFL_UI_CALENDAR_DATA_GET(obj, sd);
717
718 day = _get_item_day(obj, unfocused_it);
719 if (!day)
720 return;
721
722 sd->focused_it = -1;
723
724 snprintf(emission, sizeof(emission), "cit_%d,unfocused", unfocused_it);
725 elm_layout_signal_emit(obj, emission, "elm");
726}
727
728static Eina_Bool
729_update_focused_it(Evas_Object *obj, int focused_it)
730{
731 int day;
732 char emission[32];
733
734 EFL_UI_CALENDAR_DATA_GET(obj, sd);
735
736 day = _get_item_day(obj, focused_it);
737 if (!day)
738 return EINA_FALSE;
739
740 snprintf(emission, sizeof(emission), "cit_%d,unfocused", sd->focused_it);
741 elm_layout_signal_emit(obj, emission, "elm");
742
743 sd->focused_it = focused_it;
744
745 snprintf(emission, sizeof(emission), "cit_%d,focused", sd->focused_it);
746 elm_layout_signal_emit(obj, emission, "elm");
747
748 return EINA_TRUE;
749}
750
751static void
752_update_sel_it(Evas_Object *obj,
753 int sel_it)
754{
755 int day;
756
757 EFL_UI_CALENDAR_DATA_GET(obj, sd);
758
759 day = _get_item_day(obj, sel_it);
760 if (!day)
761 return;
762
763 _unselect(obj, sd->selected_it);
764 if (!sd->selected)
765 sd->selected = EINA_TRUE;
766 if (sd->focused_it)
767 _update_unfocused_it(obj, sd->focused_it);
768
769 sd->date.tm_mday = day;
770 _fix_date(sd);
771 _select(obj, sel_it);
772 efl_event_callback_legacy_call(obj, EFL_UI_CALENDAR_EVENT_CHANGED, NULL);
773}
774
775static void
776_day_selected(void *data,
777 Evas_Object *obj EINA_UNUSED,
778 const char *emission EINA_UNUSED,
779 const char *source)
780{
781 int sel_it;
782
783 sel_it = atoi(source);
784
785 _update_sel_it(data, sel_it);
786}
787
788static inline int
789_time_to_next_day(struct tm *t)
790{
791 return ((((24 - t->tm_hour) * 60) - t->tm_min) * 60) - t->tm_sec;
792}
793
794static Eina_Bool
795_update_cur_date(void *data)
796{
797 time_t current_date;
798 int t, day;
799 EFL_UI_CALENDAR_DATA_GET(data, sd);
800
801 if (sd->today_it > 0) _not_today(sd);
802
803 current_date = time(NULL);
804 localtime_r(&current_date, &sd->current_date);
805 t = _time_to_next_day(&sd->current_date);
806 ecore_timer_interval_set(sd->update_timer, t);
807
808 if ((sd->current_date.tm_mon != sd->shown_date.tm_mon) ||
809 (sd->current_date.tm_year != sd->shown_date.tm_year))
810 return ECORE_CALLBACK_RENEW;
811
812 day = sd->current_date.tm_mday + sd->first_day_it - 1;
813 _today(sd, day);
814
815 return ECORE_CALLBACK_RENEW;
816}
817
818static Eina_Bool
819_key_action_activate(Evas_Object *obj, const char *params EINA_UNUSED)
820{
821 EFL_UI_CALENDAR_DATA_GET(obj, sd);
822
823 _update_sel_it(obj, sd->focused_it);
824
825 return EINA_TRUE;
826}
827
828EOLIAN static Eina_Bool
829_efl_ui_calendar_elm_widget_on_focus_update(Eo *obj, Efl_Ui_Calendar_Data *sd, Elm_Object_Item *item EINA_UNUSED)
830{
831 Eina_Bool int_ret = EINA_FALSE;
832
833 int_ret = efl_ui_widget_on_focus_update(efl_super(obj, MY_CLASS), NULL);
834 if (!int_ret) return EINA_FALSE;
835
836 // FIXME : Currently, focused item is same with selected item.
837 // After arrenging focus logic in this widget, we need to make
838 // focused item which is for indicating direction key input movement
839 // on the calendar widget.
840 if (elm_widget_focus_get(obj))
841 _update_focused_it(obj, sd->selected_it);
842 else
843 _update_unfocused_it(obj, sd->focused_it);
844
845 return EINA_TRUE;
846}
847
848EOLIAN static void
849_efl_ui_calendar_efl_canvas_group_group_calculate(Eo *obj, Efl_Ui_Calendar_Data *_pd EINA_UNUSED)
850{
851 elm_layout_freeze(obj);
852
853 _set_headers(obj);
854 _populate(obj);
855
856 elm_layout_thaw(obj);
857}
858
859EOLIAN static void
860_efl_ui_calendar_efl_object_destructor(Eo *obj, Efl_Ui_Calendar_Data *sd)
861{
862 int i;
863
864 ecore_timer_del(sd->spin_month);
865 ecore_timer_del(sd->spin_year);
866 ecore_timer_del(sd->update_timer);
867
868 for (i = 0; i < ELM_DAY_LAST; i++)
869 eina_stringshare_del(sd->weekdays[i]);
870
871 efl_destructor(efl_super(obj, MY_CLASS));
872}
873
874static void
875_access_obj_process(Evas_Object *obj, Eina_Bool is_access)
876{
877 int maxdays, day, i;
878
879 EFL_UI_CALENDAR_DATA_GET(obj, sd);
880 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
881
882 if (is_access)
883 _access_calendar_register(obj);
884 else
885 {
886 day = 0;
887 maxdays = _maxdays_get(&sd->shown_date, 0);
888 for (i = 0; i < 42; i++)
889 {
890 if ((!day) && (i == sd->first_day_it)) day = 1;
891 if ((day) && (day <= maxdays))
892 {
893 char pname[14];
894 snprintf(pname, sizeof(pname), "cit_%d.access", i);
895
896 _elm_access_edje_object_part_object_unregister
897 (obj, elm_layout_edje_get(obj), pname);
898 }
899 }
900
901 if (sd->dec_btn_month && efl_isa(sd->dec_btn_month, ELM_ACCESS_CLASS))
902 {
903 _elm_access_edje_object_part_object_unregister
904 (obj, elm_layout_edje_get(obj), "left_bt");
905 sd->dec_btn_month = NULL;
906 }
907 if (sd->inc_btn_month && efl_isa(sd->inc_btn_month, ELM_ACCESS_CLASS))
908 {
909 _elm_access_edje_object_part_object_unregister
910 (obj, elm_layout_edje_get(obj), "right_bt");
911 sd->inc_btn_month = NULL;
912 }
913 if (sd->month_access)
914 _elm_access_edje_object_part_object_unregister
915 (obj, elm_layout_edje_get(obj), "month_text");
916 }
917}
918
919EOLIAN static void
920_efl_ui_calendar_elm_widget_on_access_update(Eo *obj EINA_UNUSED, Efl_Ui_Calendar_Data *_pd EINA_UNUSED, Eina_Bool acs)
921{
922 _efl_ui_calendar_smart_focus_next_enable = acs;
923 _access_obj_process(obj, _efl_ui_calendar_smart_focus_next_enable);
924}
925
926static Eo *
927_efl_ui_calendar_constructor_internal(Eo *obj, Efl_Ui_Calendar_Data *priv)
928{
929 time_t current_date;
930 int t;
931
932 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, NULL);
933
934 elm_widget_sub_object_parent_add(obj);
935
936 priv->first_interval = 0.85;
937 priv->date_min.tm_year = 2;
938 priv->date_min.tm_mon = 0;
939 priv->date_min.tm_mday = 1;
940 priv->date_max.tm_year = -1;
941 priv->date_max.tm_mon = 11;
942 priv->date_max.tm_mday = 31;
943 priv->today_it = -1;
944 priv->selected_it = -1;
945 priv->first_day_it = -1;
946 priv->format_func = _format_month_year;
947
948 edje_object_signal_callback_add
949 (wd->resize_obj, "elm,action,selected", "*",
950 _day_selected, obj);
951
952 current_date = time(NULL);
953 localtime_r(&current_date, &priv->shown_date);
954 priv->current_date = priv->shown_date;
955 priv->date = priv->shown_date;
956 t = _time_to_next_day(&priv->current_date);
957 priv->update_timer = ecore_timer_add(t, _update_cur_date, obj);
958
959 elm_widget_can_focus_set(obj, EINA_TRUE);
960
961 if (!elm_layout_theme_set(obj, "calendar", "base",
962 elm_object_style_get(obj)))
963 CRI("Failed to set layout!");
964
965 _spinner_buttons_add(obj, priv);
966
967 evas_object_smart_changed(obj);
968
969 // ACCESS
970 if ((_elm_config->access_mode != ELM_ACCESS_MODE_OFF))
971 _access_calendar_spinner_register(obj);
972
973 return obj;
974}
975
976EOLIAN static Eo *
977_efl_ui_calendar_efl_object_constructor(Eo *obj, Efl_Ui_Calendar_Data *sd)
978{
979 obj = efl_constructor(efl_super(obj, MY_CLASS));
980 sd->obj = obj;
981 evas_object_smart_callbacks_descriptions_set(obj, _smart_callbacks);
982 efl_access_role_set(obj, EFL_ACCESS_ROLE_DATE_EDITOR);
983
984 obj = _efl_ui_calendar_constructor_internal(obj, sd);
985
986 return obj;
987}
988
989EOLIAN static Eina_Bool
990_efl_ui_calendar_date_min_set(Eo *obj, Efl_Ui_Calendar_Data *sd, Efl_Time min)
991{
992 Eina_Bool upper = EINA_FALSE;
993 struct tm temp;
994
995 temp = min;
996 if (mktime(&temp) == -1)
997 {
998 ERR("mktime can not give week day for your minimum date. Please check the date.");
999 return EINA_FALSE;
1000 }
1001
1002 if ((sd->date_min.tm_year == min.tm_year)
1003 && (sd->date_min.tm_mon == min.tm_mon)
1004 && (sd->date_min.tm_mday == min.tm_mday))
1005 return EINA_TRUE;
1006
1007 if (min.tm_year < 2)
1008 {
1009 sd->date_min.tm_year = 2;
1010 sd->date_min.tm_mon = 0;
1011 sd->date_min.tm_mday = 1;
1012 }
1013 else
1014 {
1015 if (sd->date_max.tm_year != -1)
1016 {
1017 if (min.tm_year > sd->date_max.tm_year)
1018 {
1019 upper = EINA_TRUE;
1020 }
1021 else if (min.tm_year == sd->date_max.tm_year)
1022 {
1023 if (min.tm_mon > sd->date_max.tm_mon)
1024 upper = EINA_TRUE;
1025 else if ((min.tm_mon == sd->date_max.tm_mon) && (min.tm_mday > sd->date_max.tm_mday))
1026 upper = EINA_TRUE;
1027 }
1028 }
1029
1030 if (upper)
1031 {
1032 sd->date_min.tm_year = sd->date_max.tm_year;
1033 sd->date_min.tm_mon = sd->date_max.tm_mon;
1034 sd->date_min.tm_mday = sd->date_max.tm_mday;
1035 }
1036 else
1037 {
1038 sd->date_min.tm_year = min.tm_year;
1039 sd->date_min.tm_mon = min.tm_mon;
1040 sd->date_min.tm_mday = min.tm_mday;
1041 }
1042 }
1043
1044 _fix_date(sd);
1045
1046 evas_object_smart_changed(obj);
1047
1048 if (upper)
1049 {
1050 ERR("Your minimum date is greater than current maximum date.");
1051 return EINA_FALSE;
1052 }
1053 return EINA_TRUE;
1054}
1055
1056EOLIAN static Efl_Time
1057_efl_ui_calendar_date_min_get(Eo *obj EINA_UNUSED, Efl_Ui_Calendar_Data *sd)
1058{
1059 return sd->date_min;
1060}
1061
1062EOLIAN static Eina_Bool
1063_efl_ui_calendar_date_max_set(Eo *obj, Efl_Ui_Calendar_Data *sd, Efl_Time max)
1064{
1065 Eina_Bool lower = EINA_FALSE;
1066 struct tm temp;
1067
1068 temp = max;
1069 if (mktime(&temp) == -1)
1070 {
1071 ERR("mktime can not give week day for your maximum date. Please check the date.");
1072 return EINA_FALSE;
1073 }
1074
1075 if ((sd->date_max.tm_year == max.tm_year)
1076 && (sd->date_max.tm_mon == max.tm_mon)
1077 && (sd->date_max.tm_mday == max.tm_mday))
1078 return EINA_TRUE;
1079
1080 if (max.tm_year < sd->date_min.tm_year)
1081 {
1082 lower = EINA_TRUE;
1083 }
1084 else if (max.tm_year == sd->date_min.tm_year)
1085 {
1086 if (max.tm_mon < sd->date_min.tm_mon)
1087 lower = EINA_TRUE;
1088 else if ((max.tm_mon == sd->date_min.tm_mon) && (max.tm_mday < sd->date_min.tm_mday))
1089 lower = EINA_TRUE;
1090 }
1091
1092 if (lower)
1093 {
1094 sd->date_max.tm_year = sd->date_min.tm_year;
1095 sd->date_max.tm_mon = sd->date_min.tm_mon;
1096 sd->date_max.tm_mday = sd->date_min.tm_mday;
1097 }
1098 else
1099 {
1100 sd->date_max.tm_year = max.tm_year;
1101 sd->date_max.tm_mon = max.tm_mon;
1102 sd->date_max.tm_mday = max.tm_mday;
1103 }
1104
1105 _fix_date(sd);
1106
1107 evas_object_smart_changed(obj);
1108
1109 if (lower)
1110 {
1111 ERR("Your maximum date is less than current minimum date.");
1112 return EINA_FALSE;
1113 }
1114 return EINA_TRUE;
1115}
1116
1117EOLIAN static Efl_Time
1118_efl_ui_calendar_date_max_get(Eo *obj EINA_UNUSED, Efl_Ui_Calendar_Data *sd)
1119{
1120 return sd->date_max;
1121}
1122
1123EOLIAN static Eina_Bool
1124_efl_ui_calendar_date_set(Eo *obj, Efl_Ui_Calendar_Data *sd, Efl_Time date)
1125{
1126 Eina_Bool ret = EINA_TRUE;
1127 struct tm temp;
1128
1129 temp = date;
1130 if (mktime(&temp) == -1)
1131 {
1132 ERR("mktime can not give week day for your new date. Please check the date.");
1133 return EINA_FALSE;
1134 }
1135
1136 sd->date.tm_year = date.tm_year;
1137 sd->date.tm_mon = date.tm_mon;
1138 sd->date.tm_mday = date.tm_mday;
1139 if (!sd->selected)
1140 sd->selected = EINA_TRUE;
1141
1142 if (sd->date.tm_year != sd->shown_date.tm_year)
1143 sd->shown_date.tm_year = sd->date.tm_year;
1144 if (sd->date.tm_mon != sd->shown_date.tm_mon)
1145 sd->shown_date.tm_mon = sd->date.tm_mon;
1146
1147 ret = _fix_date(sd);
1148
1149 evas_object_smart_changed(obj);
1150
1151 if (!ret)
1152 ERR("The current date is greater than the maximum date or less than the minimum date.");
1153
1154 return ret;
1155}
1156
1157EOLIAN static Efl_Time
1158_efl_ui_calendar_date_get(Eo *obj EINA_UNUSED, Efl_Ui_Calendar_Data *sd)
1159{
1160 return sd->date;
1161}
1162
1163EOLIAN static void
1164_efl_ui_calendar_format_function_set(Eo *obj EINA_UNUSED, Efl_Ui_Calendar_Data *sd, Efl_Ui_Calendar_Format_Cb format_function)
1165{
1166 sd->format_func = format_function;
1167}
1168
1169EOLIAN static void
1170_efl_ui_calendar_first_day_of_week_set(Eo *obj, Efl_Ui_Calendar_Data *sd, Efl_Ui_Calendar_Weekday day)
1171{
1172 if (day >= EFL_UI_CALENDAR_WEEKDAY_LAST) return;
1173 if (sd->first_week_day != day)
1174 {
1175 sd->first_week_day = day;
1176 evas_object_smart_changed(obj);
1177 }
1178}
1179
1180EOLIAN static Efl_Ui_Calendar_Weekday
1181_efl_ui_calendar_first_day_of_week_get(Eo *obj EINA_UNUSED, Efl_Ui_Calendar_Data *sd)
1182{
1183 return sd->first_week_day;
1184}
1185
1186static void
1187_efl_ui_calendar_class_constructor(Efl_Class *klass)
1188{
1189 evas_smart_legacy_type_register(MY_CLASS_NAME, klass);
1190
1191 if (_elm_config->access_mode != ELM_ACCESS_MODE_OFF)
1192 _efl_ui_calendar_smart_focus_next_enable = EINA_TRUE;
1193}
1194
1195EOLIAN static const Elm_Atspi_Action*
1196_efl_ui_calendar_elm_interface_atspi_widget_action_elm_actions_get(Eo *obj EINA_UNUSED, Efl_Ui_Calendar_Data *sd EINA_UNUSED)
1197{
1198 static Elm_Atspi_Action atspi_actions[] = {
1199 { "activate", "activate", NULL, _key_action_activate},
1200 { NULL, NULL, NULL, NULL }
1201 };
1202 return &atspi_actions[0];
1203}
1204
1205/* Standard widget overrides */
1206
1207ELM_WIDGET_KEY_DOWN_DEFAULT_IMPLEMENT(efl_ui_calendar, Efl_Ui_Calendar_Data)
1208
1209/* Internal EO APIs and hidden overrides */
1210
1211#define EFL_UI_CALENDAR_EXTRA_OPS \
1212 ELM_LAYOUT_SIZING_EVAL_OPS(efl_ui_calendar)
1213
1214#include "efl_ui_calendar.eo.c"
diff --git a/src/lib/elementary/efl_ui_calendar.eo b/src/lib/elementary/efl_ui_calendar.eo
new file mode 100644
index 0000000000..6615fa90fb
--- /dev/null
+++ b/src/lib/elementary/efl_ui_calendar.eo
@@ -0,0 +1,149 @@
1import efl_types;
2
3type Efl_Ui_Calendar_Format_Cb: __undefined_type; [[Elementary calendar format callback type]]
4
5enum Efl.Ui.Calendar.Weekday
6{
7 [[A weekday
8
9 See also @Efl.Ui.Calendar.first_day_of_week.set.
10 ]]
11 sunday, [[Sunday weekday]]
12 monday, [[Monday weekday]]
13 tuesday, [[Tusday weekday]]
14 wednesday, [[Wednesday weekday]]
15 thursday, [[Thursday weekday]]
16 friday, [[Friday weekday]]
17 saturday, [[Saturday weekday]]
18 last [[Sentinel value to indicate last enum field during iteration]]
19}
20
21class Efl.Ui.Calendar (Efl.Ui.Layout, Efl.Ui.Focus.Composition, Elm.Interface.Atspi_Widget_Action)
22{
23 [[Calendar widget
24
25 It helps applications to flexibly display a calendar with day of the week,
26 date, year and month. Applications are able to set specific dates to be
27 reported back, when selected, in the smart callbacks of the calendar widget.
28 ]]
29 methods {
30 @property first_day_of_week {
31 [[The first day of week to use on calendar widgets'.]]
32 set {
33 }
34 get {
35 }
36 values {
37 day: Efl.Ui.Calendar.Weekday(Efl.Ui.Calendar.Weekday.sunday); [[Weekday enum value, see @Elm.Calendar.Weekday]]
38 }
39 }
40 @property format_function {
41 set {
42 [[Set a function to format the string that will be used to display
43 month and year;
44
45 By default it uses strftime with "%B %Y" format string.
46 It should allocate the memory that will be used by the string,
47 that will be freed by the widget after usage.
48 A pointer to the string and a pointer to the time struct will be provided.
49 ]]
50 /* FIXME-doc
51 * Example:
52 * @code
53 * static char
54 * _format_month_year(struct tm *selected_time)
55 * {
56 * char buf[32];
57 * if (!strftime(buf, sizeof(buf), "%B %Y", selected_time)) return NULL;
58 * return strdup(buf);
59 * }
60 *
61 * efl_ui_calendar_format_function_set(calendar, _format_month_year);
62 * @endcode
63 */
64 }
65 values {
66 format_function: Efl_Ui_Calendar_Format_Cb; [[Function to set the month-year string given
67 the selected date.]]
68 }
69 }
70 @property date_min {
71 [[Minimum date on calendar.]]
72 set {
73 [[Set the minimum date on calendar.
74
75 Set the minimum date, changing the displayed month or year if needed.
76 Displayed day also to be disabled if it is smaller than minimum date.
77 If the minimum date is greater than current maximum date, the minimum
78 date would be changed to the maximum date with returning $false.
79 ]]
80 return: bool; [[$true, on success, $false otherwise]]
81 }
82 get {
83 [[Get the minimum date.
84
85 Default value is 1 JAN,1902.
86 ]]
87 }
88 values {
89 min: Efl.Time; [[Time structure containing the minmum date.]]
90 }
91 }
92 @property date_max {
93 [[Maximum date on calendar.]]
94 set {
95 [[Set the maximum date on calendar.
96
97 Set the maximum date, changing the displayed month or year if needed.
98 Displayed day also to be disabled if it is bigger than maximum date.
99 If the maximum date is less than current minimum date, the maximum date
100 would be changed to the minimum date with returning $false.
101 ]]
102 return: bool; [[$true, on success, $false otherwise]]
103 }
104 get {
105 [[Get the maximum date.
106
107 Default maximum year is -1.
108 Default maximum day and month are 31 and DEC.
109
110 If the maximum year is a negative value, it will be limited depending
111 on the platform architecture (year 2037 for 32 bits);
112 ]]
113 }
114 values {
115 max: Efl.Time; [[Time structure containing the maximum date.]]
116 }
117 }
118 @property date {
119 [[The selected date on calendar.]]
120 set {
121 [[Set the selected date. If the date is greater than the maximum date,
122 the date would be changed to the maximum date with returning $false.
123 In the opposite case with the minimum date,
124 this would give the same result.
125 ]]
126 return: bool; [[$true, on success, $false otherwise]]
127 }
128 get {
129 }
130 values {
131 date: Efl.Time; [[Time structure containing the selected date.]]
132 }
133 }
134 }
135 implements {
136 class.constructor;
137 Efl.Object.constructor;
138 Efl.Object.destructor;
139 Efl.Canvas.Group.group_calculate;
140 Elm.Widget.theme_apply;
141 Elm.Widget.on_access_update;
142 Elm.Widget.on_focus_update;
143 Elm.Widget.widget_event;
144 Elm.Interface.Atspi_Widget_Action.elm_actions { get; }
145 }
146 events {
147 changed; [[Emitted when the selected date in the calendar is changed]]
148 }
149}
diff --git a/src/lib/elementary/efl_ui_calendar.h b/src/lib/elementary/efl_ui_calendar.h
new file mode 100644
index 0000000000..9c71188b47
--- /dev/null
+++ b/src/lib/elementary/efl_ui_calendar.h
@@ -0,0 +1,57 @@
1/**
2 * @defgroup Elm_Calendar Calendar
3 * @ingroup Elementary
4 *
5 * @image html calendar_inheritance_tree.png
6 * @image latex calendar_inheritance_tree.eps
7 *
8 * This is a calendar widget. It helps applications to flexibly
9 * display a calendar with day of the week, date, year and
10 * month. Applications are able to set specific dates to be reported
11 * back, when selected, in the smart callbacks of the calendar
12 * widget. The API of this widget lets the applications perform other
13 * functions, like:
14 *
15 * - placing marks on specific dates
16 * - setting the bounds for the calendar (minimum and maximum years)
17 * - setting the day names of the week (e.g. "Thu" or "Thursday")
18 * - setting the year and month format.
19 *
20 * This widget inherits from the @ref Layout one, so that all the
21 * functions acting on it also work for calendar objects.
22 *
23 * This widget emits the following signals, besides the ones sent from
24 * @ref Layout:
25 * - @c "changed" - emitted when the date in the calendar is changed.
26 * - @c "display,changed" - emitted when the current month displayed in the
27 * calendar is changed.
28 * - @c "focused" - When the calendar has received focus. (since 1.8)
29 * - @c "unfocused" - When the calendar has lost focus. (since 1.8)
30 * - @c "language,changed" - the program's language changed (since 1.9)
31 *
32 * Supported elm_object common APIs.
33 * @li @ref elm_object_signal_emit
34 * @li @ref elm_object_signal_callback_add
35 * @li @ref elm_object_signal_callback_del
36 *
37 * Here is some sample code using it:
38 * @li @ref calendar_example_01
39 * @li @ref calendar_example_02
40 * @li @ref calendar_example_03
41 * @li @ref calendar_example_04
42 * @li @ref calendar_example_05
43 * @li @ref calendar_example_06
44 */
45
46/**
47 * @addtogroup Elm_Calendar
48 * @{
49 */
50
51#include "efl_ui_calendar_common.h"
52#ifdef EFL_EO_API_SUPPORT
53#include "efl_ui_calendar.eo.h"
54#endif
55/**
56 * @}
57 */
diff --git a/src/lib/elementary/efl_ui_calendar_common.h b/src/lib/elementary/efl_ui_calendar_common.h
new file mode 100644
index 0000000000..70a95ad8f2
--- /dev/null
+++ b/src/lib/elementary/efl_ui_calendar_common.h
@@ -0,0 +1,21 @@
1/**
2 * @addtogroup Elm_Calendar
3 *
4 * @{
5 */
6
7/**
8 * This callback type is used to format the string that will be used
9 * to display month and year.
10 *
11 * @param stime Struct representing time.
12 * @return String representing time that will be set to calendar's text.
13 *
14 * @see elm_calendar_format_function_set()
15 */
16typedef char * (*Efl_Ui_Calendar_Format_Cb)(struct tm *stime);
17
18
19/**
20 * @}
21 */
diff --git a/src/lib/elementary/efl_ui_calendar_private.h b/src/lib/elementary/efl_ui_calendar_private.h
new file mode 100644
index 0000000000..7ae261cfa9
--- /dev/null
+++ b/src/lib/elementary/efl_ui_calendar_private.h
@@ -0,0 +1,65 @@
1#ifndef EFL_UI_CALENDAR_PRIVATE_H
2#define ELM_WIDGET_CALENDAR_H
3
4#include "Elementary.h"
5
6/* DO NOT USE THIS HEADER UNLESS YOU ARE PREPARED FOR BREAKING OF YOUR
7 * CODE. THIS IS ELEMENTARY'S INTERNAL WIDGET API (for now) AND IS NOT
8 * FINAL. CALL elm_widget_api_check(ELM_INTERNAL_API_VERSION) TO CHECK
9 * IT AT RUNTIME.
10 */
11
12/**
13 * @addtogroup Widget
14 * @{
15 *
16 * @section elm-calendar-class The Elementary Calendar Class
17 *
18 * Elementary, besides having the @ref Calendar widget, exposes its
19 * foundation -- the Elementary Calendar Class -- in order to create other
20 * widgets which are a calendar with some more logic on top.
21 */
22
23/**
24 * Base layout smart data extended with calendar instance data.
25 */
26typedef struct _Efl_Ui_Calendar_Data Efl_Ui_Calendar_Data;
27
28struct _Efl_Ui_Calendar_Data
29{
30 Evas_Object *obj; // the object itself
31 double interval, first_interval;
32 int spin_speed;
33 int today_it, selected_it, focused_it;
34 Ecore_Timer *spin_month, *spin_year, *update_timer;
35 Efl_Ui_Calendar_Format_Cb format_func;
36 const char *weekdays[ELM_DAY_LAST];
37 struct tm current_date, shown_date, date, date_min, date_max;
38 Evas_Object *inc_btn_month;
39 Evas_Object *dec_btn_month;
40 Evas_Object *month_access;
41 Evas_Object *inc_btn_year;
42 Evas_Object *dec_btn_year;
43 Evas_Object *year_access;
44 Eo *items[42];
45
46 Efl_Ui_Calendar_Weekday first_week_day;
47
48 unsigned char first_day_it;
49
50 Eina_Bool selected : 1;
51 Eina_Bool double_spinners : 1;
52 Eina_Bool filling : 1;
53 Eina_Bool weekdays_set : 1;
54 Eina_Bool month_repeated : 1;
55 Eina_Bool year_repeated : 1;
56};
57
58/**
59 * @}
60 */
61
62#define EFL_UI_CALENDAR_DATA_GET(o, sd) \
63 Efl_Ui_Calendar_Data * sd = efl_data_scope_get(o, EFL_UI_CALENDAR_CLASS)
64
65#endif