summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/elementary/themes/Makefile.am2
-rw-r--r--data/elementary/themes/default.edc2
-rw-r--r--data/elementary/themes/edc/efl/button.edc16
-rw-r--r--data/elementary/themes/edc/efl/datepicker.edc183
-rw-r--r--data/elementary/themes/edc/efl/spin_button.edc720
-rw-r--r--data/elementary/themes/edc/efl/timepicker.edc378
-rw-r--r--data/elementary/themes/edc/elm/button.edc24
-rw-r--r--data/elementary/themes/edc/elm/entry.edc1
-rw-r--r--src/Makefile_Efl.am4
-rw-r--r--src/Makefile_Elementary.am8
-rw-r--r--src/bin/elementary/Makefile.am2
-rw-r--r--src/bin/elementary/test.c4
-rw-r--r--src/bin/elementary/test_ui_datepicker.c37
-rw-r--r--src/bin/elementary/test_ui_timepicker.c36
-rw-r--r--src/lib/efl/CMakeLists.txt2
-rw-r--r--src/lib/efl/Efl.h3
-rw-r--r--src/lib/efl/interfaces/efl_interfaces_main.c2
-rw-r--r--src/lib/efl/interfaces/efl_ui_date.eo63
-rw-r--r--src/lib/efl/interfaces/efl_ui_datetime.c176
-rw-r--r--src/lib/efl/interfaces/efl_ui_datetime.eo38
-rw-r--r--src/lib/efl/interfaces/efl_ui_time.eo19
-rw-r--r--src/lib/elementary/Elementary.h2
-rw-r--r--src/lib/elementary/efl_ui_datepicker.c352
-rw-r--r--src/lib/elementary/efl_ui_datepicker.eo21
-rw-r--r--src/lib/elementary/efl_ui_datepicker_private.h22
-rw-r--r--src/lib/elementary/efl_ui_timepicker.c282
-rw-r--r--src/lib/elementary/efl_ui_timepicker.eo26
-rw-r--r--src/lib/elementary/efl_ui_timepicker_private.h21
28 files changed, 2186 insertions, 260 deletions
diff --git a/data/elementary/themes/Makefile.am b/data/elementary/themes/Makefile.am
index e91113c1cc..b98c48cf34 100644
--- a/data/elementary/themes/Makefile.am
+++ b/data/elementary/themes/Makefile.am
@@ -1034,6 +1034,8 @@ elementary/themes/edc/efl/scroller.edc \
elementary/themes/edc/efl/slider.edc \
elementary/themes/edc/efl/spin.edc \
elementary/themes/edc/efl/spin_button.edc \
+elementary/themes/edc/efl/datepicker.edc \
+elementary/themes/edc/efl/timepicker.edc \
elementary/themes/edc/efl/text.edc \
elementary/themes/edc/efl/textpath.edc \
elementary/themes/edc/efl/tooltip.edc \
diff --git a/data/elementary/themes/default.edc b/data/elementary/themes/default.edc
index 3b851409f5..cea6232ce6 100644
--- a/data/elementary/themes/default.edc
+++ b/data/elementary/themes/default.edc
@@ -189,6 +189,8 @@ collections {
#include "edc/efl/border.edc"
#include "edc/efl/spin.edc"
#include "edc/efl/spin_button.edc"
+#include "edc/efl/datepicker.edc"
+#include "edc/efl/timepicker.edc"
// XXX: min size calc problems - too wide! ... err ok on my 32bit box... eh?
#include "edc/efl/cursor.edc"
#include "edc/efl/pointer.edc"
diff --git a/data/elementary/themes/edc/efl/button.edc b/data/elementary/themes/edc/efl/button.edc
index 9853358e67..5ad13977c9 100644
--- a/data/elementary/themes/edc/efl/button.edc
+++ b/data/elementary/themes/edc/efl/button.edc
@@ -781,3 +781,19 @@ group { name: "efl/button:anchor";
#undef MASK
#undef DISABLE
}
+
+group { "efl/button:ampm";
+ inherit: "efl/button";
+ parts {
+ image { "base";
+ desc { "default";
+ min: 40 40;
+ max: 40 40;
+ }
+ desc { "pressed";
+ min: 40 40;
+ max: 40 40;
+ }
+ }
+ }
+}
diff --git a/data/elementary/themes/edc/efl/datepicker.edc b/data/elementary/themes/edc/efl/datepicker.edc
new file mode 100644
index 0000000000..2d88e580a3
--- /dev/null
+++ b/data/elementary/themes/edc/efl/datepicker.edc
@@ -0,0 +1,183 @@
+group { "efl/datepicker";
+ parts {
+ spacer { "base";
+ scale;
+ desc { "default";
+ min: 150 170;
+ }
+ }
+ rect { "base_bg";
+ scale;
+ desc { "default";
+ rel.to: "base";
+ color: 0 0 0 35;
+ }
+ }
+ spacer { "padding_bg_top";
+ scale;
+ desc { "default";
+ min: 0 10;
+ max: -1 10;
+ fixed: 0 1;
+ rel1 {
+ relative: 0.0 0.0;
+ to: "base_bg";
+ }
+ rel2 {
+ relative: 1.0 0.0;
+ to: "base_bg";
+ }
+ align: 0.5 0.0;
+ }
+ }
+ spacer { "padding_bg_bottom";
+ scale;
+ desc { "default";
+ min: 0 10;
+ max: -1 10;
+ fixed: 0 1;
+ rel1 {
+ relative: 0.0 1.0;
+ to: "base_bg";
+ }
+ rel2 {
+ relative: 1.0 1.0;
+ to: "base_bg";
+ }
+ align: 0.5 1.0;
+ }
+ }
+ spacer { "bg";
+ scale;
+ desc { "default";
+ min: 150 150;
+ max: 150 150;
+ rel1 {
+ relative: 0.0 1.0;
+ to: "padding_bg_top";
+ }
+ rel2 {
+ relative: 1.0 0.0;
+ to: "padding_bg_bottom";
+ }
+ }
+ }
+ spacer { "padding_left";
+ scale;
+ desc { "default";
+ min: 5 0;
+ max: 5 -1;
+ fixed: 1 0;
+ rel1 {
+ relative: 0.0 0.0;
+ to: "bg";
+ }
+ rel2 {
+ relative: 0.0 1.0;
+ to: "bg";
+ }
+ align: 0.0 0.0;
+ }
+ }
+ spacer { "padding_right";
+ scale;
+ desc { "default";
+ min: 5 0;
+ max: 5 -1;
+ fixed: 1 0;
+ rel2.to: "bg";
+ rel1 {
+ relative: 1.0 0.0;
+ to: "bg";
+ }
+ rel2 {
+ relative: 1.0 1.0;
+ to: "bg";
+ }
+ align: 1.0 1.0;
+ }
+ }
+ swallow { "field0";
+ mouse;
+ scale;
+ desc { "default";
+ fixed: 1 0;
+ min: 40 0;
+ rel1 {
+ relative: 1.0 0.0;
+ to: "padding_left";
+ }
+ rel2.to: "padding_left";
+ align: 0.0 0.5;
+ }
+ }
+ spacer { "padding_center1";
+ scale;
+ desc { "default";
+ fixed: 1 0;
+ min: 10 0;
+ max: 10 -1;
+ rel1 {
+ relative: 1.0 0.0;
+ to: "field0";
+ }
+ rel2.to: "field0";
+ align: 0.0 0.5;
+ }
+ }
+ swallow { "field1";
+ mouse;
+ scale;
+ desc { "default";
+ fixed: 1 0;
+ min: 40 0;
+ rel1 {
+ relative: 1.0 0.0;
+ to: "padding_center1";
+ }
+ rel2 {
+ relative: 0.0 1.0;
+ to_x: "padding_center2";
+ to_y: "padding_center1";
+ }
+ }
+ }
+ spacer { "padding_center2";
+ scale;
+ desc { "default";
+ fixed: 1 0;
+ min: 10 0;
+ max: 10 -1;
+ rel1.to: "field2";
+ rel2 {
+ relative: 0.0 1.0;
+ to: "field2";
+ }
+ align: 1.0 0.5;
+ }
+ }
+ swallow { "field2";
+ mouse;
+ scale;
+ desc { "default";
+ fixed: 1 0;
+ min: 40 0;
+ rel1.to: "padding_right";
+ rel2 {
+ relative: 0.0 1.0;
+ to: "padding_right";
+ }
+ align: 1.0 0.5;
+ }
+ }
+ rect { "access";
+ repeat;
+ desc { "default";
+ fixed: 1 1;
+ rel1.to: "bg";
+ rel2.to: "bg";
+ color: 0 0 0 0;
+ }
+ }
+ }
+}
diff --git a/data/elementary/themes/edc/efl/spin_button.edc b/data/elementary/themes/edc/efl/spin_button.edc
index 4d502e3779..e6e7f5c6c8 100644
--- a/data/elementary/themes/edc/efl/spin_button.edc
+++ b/data/elementary/themes/edc/efl/spin_button.edc
@@ -207,303 +207,503 @@ group { "efl/spin_button:vertical";
}
group { name: "efl/spin_button/inc_button";
- images.image: "sym_right_light_normal.png" COMP;
- images.image: "sym_right_glow_normal.png" COMP;
- images.image: "sym_right_dark_normal.png" COMP;
- script {
- public mouse_down = 0;
- public multi_down = 0;
- }
- parts {
- part { name: "arrow.image";
- scale: 1;
- description { state: "default" 0.0;
- min: 15 15;
- max: 15 15;
- color_class: "F032L1";
- image.normal: "sym_right_light_normal.png";
- }
- description { state: "pressed" 0.0;
- inherit: "default" 0.0;
- image.normal: "sym_right_glow_normal.png";
- }
- description { state: "disabled" 0.0;
- inherit: "default" 0.0;
- image.normal: "sym_right_dark_normal.png";
- }
+ images.image: "sym_right_light_normal.png" COMP;
+ images.image: "sym_right_glow_normal.png" COMP;
+ images.image: "sym_right_dark_normal.png" COMP;
+ script {
+ public mouse_down = 0;
+ public multi_down = 0;
+ }
+ parts {
+ part { name: "arrow.image";
+ scale: 1;
+ description { state: "default" 0.0;
+ min: 15 15;
+ max: 15 15;
+ color_class: "F032L1";
+ image.normal: "sym_right_light_normal.png";
}
- part { name: "over";
- type: RECT;
- repeat_events: 1;
- description { state: "default" 0.0;
- color: 0 0 0 0;
- }
+ description { state: "pressed" 0.0;
+ inherit: "default" 0.0;
+ image.normal: "sym_right_glow_normal.png";
}
- part { name: "disabler";
- type: RECT;
- description { state: "default" 0.0;
- color: 0 0 0 0;
- visible: 0;
- }
- description { state: "disabled" 0.0;
- inherit: "default" 0.0;
- visible: 1;
- }
+ description { state: "disabled" 0.0;
+ inherit: "default" 0.0;
+ image.normal: "sym_right_dark_normal.png";
}
}
- programs {
- program { name: "button_press";
- signal: "mouse,down,1";
- source: "over";
- script {
- if ((get_int(multi_down) == 0) &&
- (get_int(mouse_down) == 0)) {
- set_int(mouse_down, 1);
- run_program(PROGRAM:"button_press2");
- }
- }
- }
- program { name: "button_press2";
- action: SIGNAL_EMIT "elm,action,press" "";
- after: "button_press_anim";
- }
- program { name: "button_press_anim";
- action: STATE_SET "pressed" 0.0;
- target: "arrow.image";
- }
- program { name: "button_unpress";
- signal: "mouse,up,1";
- source: "over";
- script {
- if (get_int(mouse_down) == 1) {
- set_int(mouse_down, 0);
- run_program(PROGRAM:"button_unpress2");
- run_program(PROGRAM:"button_unpress_anim");
- }
- }
+ part { name: "over";
+ type: RECT;
+ repeat_events: 1;
+ description { state: "default" 0.0;
+ color: 0 0 0 0;
}
- program { name: "button_unpress2";
- action: SIGNAL_EMIT "elm,action,unpress" "";
+ }
+ part { name: "disabler";
+ type: RECT;
+ description { state: "default" 0.0;
+ color: 0 0 0 0;
+ visible: 0;
}
- program { name: "button_unpress_anim";
- action: STATE_SET "default" 0.0;
- target: "arrow.image";
+ description { state: "disabled" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
}
- program { name: "button_click";
- signal: "mouse,clicked,1";
- source: "over";
- script {
- if (get_int(multi_down) == 0) {
- run_program(PROGRAM:"button_click2");
- }
+ }
+ }
+ programs {
+ program { name: "button_press";
+ signal: "mouse,down,1";
+ source: "over";
+ script {
+ if ((get_int(multi_down) == 0) &&
+ (get_int(mouse_down) == 0)) {
+ set_int(mouse_down, 1);
+ run_program(PROGRAM:"button_press2");
}
}
- program { name: "action_unpressed";
- signal: "elm,action,unpressed";
- source: "elm";
- after: "button_unpress_anim";
- }
- program { name: "action_pressed";
- signal: "elm,action,pressed";
- source: "elm";
- after: "button_press_anim";
- }
- program { name: "button_click2";
- action: SIGNAL_EMIT "elm,action,click" "";
- }
- program { name: "access_pressed";
- signal: "elm,action,anim,activate";
- source: "elm";
- action: STATE_SET "pressed" 0.0;
- target: "arrow.image";
- after: "access_pressed_anim";
- }
- program { name: "access_pressed_anim";
- action: STATE_SET "default" 0.0;
- transition: DECELERATE 0.1;
- target: "arrow.image";
- }
- program { name: "disable";
- signal: "elm,state,disabled";
- source: "elm";
- action: STATE_SET "disabled" 0.0;
- target: "arrow.image";
- target: "disabler";
- }
- program { name: "enable";
- signal: "elm,state,enabled";
- source: "elm";
- action: STATE_SET "default" 0.0;
- target: "arrow.image";
- target: "disabler";
- }
- program {
- name: "multi_down";
- signal: "elm,action,multi,down";
- source: "elm";
- script {
- set_int(multi_down, 1);
+ }
+ program { name: "button_press2";
+ action: SIGNAL_EMIT "elm,action,press" "";
+ after: "button_press_anim";
+ }
+ program { name: "button_press_anim";
+ action: STATE_SET "pressed" 0.0;
+ target: "arrow.image";
+ }
+ program { name: "button_unpress";
+ signal: "mouse,up,1";
+ source: "over";
+ script {
+ if (get_int(mouse_down) == 1) {
+ set_int(mouse_down, 0);
+ run_program(PROGRAM:"button_unpress2");
+ run_program(PROGRAM:"button_unpress_anim");
}
}
- program {
- name: "multi_up";
- signal: "elm,action,multi,up";
- source: "elm";
- script {
- set_int(multi_down, 0);
+ }
+ program { name: "button_unpress2";
+ action: SIGNAL_EMIT "elm,action,unpress" "";
+ }
+ program { name: "button_unpress_anim";
+ action: STATE_SET "default" 0.0;
+ target: "arrow.image";
+ }
+ program { name: "button_click";
+ signal: "mouse,clicked,1";
+ source: "over";
+ script {
+ if (get_int(multi_down) == 0) {
+ run_program(PROGRAM:"button_click2");
}
}
}
+ program { name: "action_unpressed";
+ signal: "elm,action,unpressed";
+ source: "elm";
+ after: "button_unpress_anim";
+ }
+ program { name: "action_pressed";
+ signal: "elm,action,pressed";
+ source: "elm";
+ after: "button_press_anim";
+ }
+ program { name: "button_click2";
+ action: SIGNAL_EMIT "elm,action,click" "";
+ }
+ program { name: "access_pressed";
+ signal: "elm,action,anim,activate";
+ source: "elm";
+ action: STATE_SET "pressed" 0.0;
+ target: "arrow.image";
+ after: "access_pressed_anim";
+ }
+ program { name: "access_pressed_anim";
+ action: STATE_SET "default" 0.0;
+ transition: DECELERATE 0.1;
+ target: "arrow.image";
+ }
+ program { name: "disable";
+ signal: "elm,state,disabled";
+ source: "elm";
+ action: STATE_SET "disabled" 0.0;
+ target: "arrow.image";
+ target: "disabler";
+ }
+ program { name: "enable";
+ signal: "elm,state,enabled";
+ source: "elm";
+ action: STATE_SET "default" 0.0;
+ target: "arrow.image";
+ target: "disabler";
+ }
+ program {
+ name: "multi_down";
+ signal: "elm,action,multi,down";
+ source: "elm";
+ script {
+ set_int(multi_down, 1);
+ }
+ }
+ program {
+ name: "multi_up";
+ signal: "elm,action,multi,up";
+ source: "elm";
+ script {
+ set_int(multi_down, 0);
+ }
+ }
}
+}
group { name: "efl/spin_button/dec_button";
- inherit: "efl/spin_button/inc_button";
- images.image: "sym_left_light_normal.png" COMP;
- images.image: "sym_left_glow_normal.png" COMP;
- images.image: "sym_left_dark_normal.png" COMP;
- parts {
- part { name: "arrow.image";
- scale: 1;
- description { state: "default" 0.0;
- min: 15 15;
- max: 15 15;
- image.normal: "sym_left_light_normal.png";
- }
- description { state: "pressed" 0.0;
- inherit: "default" 0.0;
- image.normal: "sym_left_glow_normal.png";
- }
- description { state: "disabled" 0.0;
- inherit: "default" 0.0;
- image.normal: "sym_left_dark_normal.png";
- }
+ inherit: "efl/spin_button/inc_button";
+ images.image: "sym_left_light_normal.png" COMP;
+ images.image: "sym_left_glow_normal.png" COMP;
+ images.image: "sym_left_dark_normal.png" COMP;
+ parts {
+ part { name: "arrow.image";
+ scale: 1;
+ description { state: "default" 0.0;
+ min: 15 15;
+ max: 15 15;
+ image.normal: "sym_left_light_normal.png";
+ }
+ description { state: "pressed" 0.0;
+ inherit: "default" 0.0;
+ image.normal: "sym_left_glow_normal.png";
+ }
+ description { state: "disabled" 0.0;
+ inherit: "default" 0.0;
+ image.normal: "sym_left_dark_normal.png";
}
}
+ }
}
group { name: "efl/spin_button/text_button";
- alias: "efl/spin_button/text_button:vertical";
- parts {
- part { name: "bg";
- type: SPACER;
- scale: 1;
- description { state: "default" 0.0;
- }
+ alias: "efl/spin_button/text_button:vertical";
+ parts {
+ part { name: "bg";
+ type: SPACER;
+ scale: 1;
+ description { state: "default" 0.0;
}
- part { name: "elm.text";
- type: TEXT;
- scale: 1;
- effect: SHADOW BOTTOM;
- description { state: "default" 0.0;
- color: FN_COL_DEFAULT;
- color_class: "spinner";
- rel1.to: "bg";
- rel2.to: "bg";
- text { font: FN; size: 10;
- min: 1 1;
- text_class: "spinner";
- ellipsis: -1;
- }
- }
- description { state: "disabled" 0.0;
- inherit: "default" 0.0 ;
- color: FN_COL_DISABLE;
- color_class: "spinner_disabled";
+ }
+ part { name: "elm.text";
+ type: TEXT;
+ scale: 1;
+ effect: SHADOW BOTTOM;
+ description { state: "default" 0.0;
+ color: FN_COL_DEFAULT;
+ color_class: "spinner";
+ rel1.to: "bg";
+ rel2.to: "bg";
+ text { font: FN; size: 10;
+ min: 1 1;
+ text_class: "spinner";
+ ellipsis: -1;
}
}
- part { name: "over";
- type: RECT;
- repeat_events: 1;
- description { state: "default" 0.0;
- color: 0 0 0 0;
- }
+ description { state: "disabled" 0.0;
+ inherit: "default" 0.0 ;
+ color: FN_COL_DISABLE;
+ color_class: "spinner_disabled";
+ }
+ }
+ part { name: "over";
+ type: RECT;
+ repeat_events: 1;
+ description { state: "default" 0.0;
+ color: 0 0 0 0;
+ }
+ }
+ part { name: "disabler";
+ type: RECT;
+ description { state: "default" 0.0;
+ color: 0 0 0 0;
+ visible: 0;
+ }
+ description { state: "disabled" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ }
+ }
+ }
+ programs {
+ program { name: "button_click";
+ signal: "mouse,clicked,1";
+ source: "over";
+ script {
+ run_program(PROGRAM:"button_click2");
}
- part { name: "disabler";
- type: RECT;
- description { state: "default" 0.0;
- color: 0 0 0 0;
- visible: 0;
+ }
+ program { name: "button_click2";
+ action: SIGNAL_EMIT "elm,action,click" "";
+ }
+ program { name: "disable";
+ signal: "elm,state,disabled";
+ source: "elm";
+ action: STATE_SET "disabled" 0.0;
+ target: "disabler";
+ target: "elm.text";
+ }
+ program { name: "enable";
+ signal: "elm,state,enabled";
+ source: "elm";
+ action: STATE_SET "default" 0.0;
+ target: "disabler";
+ target: "elm.text";
+ }
+ }
+}
+
+group { "efl/spin_button:picker";
+ parts {
+ rect { "clip";
+ desc { "default";
+ rel.to: "elm.swallow.text_button";
+ }
+ }
+ spacer { "base";
+ scale;
+ desc { "default";
+ min: 40 150;
+ }
+ }
+ rect { "bg";
+ scale;
+ desc { "default";
+ color_class: "spinner_bg";
+ }
+ }
+ rect { "access";
+ repeat;
+ desc { "default";
+ fixed: 1 1;
+ color: 0 0 0 0;
+ rel1.to: "base";
+ rel2.to: "base";
+ hid;
+ }
+ desc { "active";
+ inherit: "default";
+ vis;
+ }
+ }
+ swallow { "elm.swallow.inc_button";
+ scale;
+ desc { "default";
+ align: 0.5 0.0;
+ min: 40 40;
+ max: 40 40;
+ fixed: 1 1;
+ }
+ }
+ swallow { "elm.swallow.dec_button";
+ scale;
+ desc { "default";
+ align: 0.5 1.0;
+ min: 40 40;
+ max: 40 40;
+ fixed: 1 1;
+ }
+ }
+ swallow { "elm.swallow.entry";
+ clip: "clip";
+ desc { "default";
+ fixed: 1 1;
+ rel1.to: "elm.swallow.text_button";
+ rel2.to: "elm.swallow.text_button";
+ hid;
+ }
+ desc { "active";
+ inherit: "default";
+ vis;
+ }
+ }
+ swallow { "elm.swallow.text_button";
+ scale;
+ desc { "default";
+ rel.to_x: "base";
+ rel1 {
+ to_y: "elm.swallow.inc_button";
+ relative: 0.0 1.0;
}
- description { state: "disabled" 0.0;
- inherit: "default" 0.0;
- visible: 1;
+ rel2 {
+ to_y: "elm.swallow.dec_button";
+ relative: 1.0 0.0;
}
+ min: 0 70;
+ max: -1 70;
+ fixed: 0 1;
+ }
+ desc { "inactive";
+ inherit: "default";
+ hid;
}
}
- programs {
- program { name: "button_click";
- signal: "mouse,clicked,1";
- source: "over";
- script {
- run_program(PROGRAM:"button_click2");
- }
+ rect { "disabler";
+ norepeat;
+ nomouse;
+ desc { "default";
+ color: 0 0 0 0;
+ hid;
}
- program { name: "button_click2";
- action: SIGNAL_EMIT "elm,action,click" "";
- }
- program { name: "disable";
- signal: "elm,state,disabled";
- source: "elm";
- action: STATE_SET "disabled" 0.0;
- target: "disabler";
- target: "elm.text";
- }
- program { name: "enable";
- signal: "elm,state,enabled";
- source: "elm";
- action: STATE_SET "default" 0.0;
- target: "disabler";
- target: "elm.text";
- }
- }
+ desc { "disabled";
+ inherit: "default";
+ vis;
+ }
+ }
+ }
+ programs {
+ program { "entry_active";
+ signal: "elm,state,entry,active";
+ source: "elm";
+ action: STATE_SET "active";
+ target: "elm.swallow.entry";
+ }
+ program { "entry_inactive";
+ signal: "elm,state,entry,inactive";
+ source: "elm";
+ action: STATE_SET "default";
+ target: "elm.swallow.entry";
+ }
+ program { "text_button_active";
+ signal: "elm,state,button,active";
+ source: "elm";
+ action: STATE_SET "default";
+ target: "elm.swallow.text_button";
+ }
+ program { "text_button_inactive";
+ signal: "elm,state,button,inactive";
+ source: "elm";
+ action: STATE_SET "inactive";
+ target: "elm.swallow.text_button";
+ }
+ program { "access_activate";
+ signal: "elm,state,access,active";
+ source: "elm";
+ action: STATE_SET "active";
+ target: "access";
+ }
+ program { "access_inactivate";
+ signal: "elm,state,access,inactive";
+ source: "elm";
+ action: STATE_SET "default";
+ target: "access";
+ }
+ program { "disable";
+ signal: "elm,state,disabled";
+ source: "elm";
+ action: STATE_SET "disabled";
+ target: "disabler";
+ }
+ program { "enable";
+ signal: "elm,state,enabled";
+ source: "elm";
+ action: STATE_SET "default";
+ target: "disabler";
+ }
+ }
}
group { name: "efl/spin_button/inc_button:vertical";
- inherit: "efl/spin_button/inc_button";
- images.image: "sym_up_light_normal.png" COMP;
- images.image: "sym_up_glow_normal.png" COMP;
- images.image: "sym_up_dark_normal.png" COMP;
- parts {
- part { name: "arrow.image";
- scale: 1;
- description { state: "default" 0.0;
- min: 15 15;
- max: 15 15;
- image.normal: "sym_up_light_normal.png";
- }
- description { state: "pressed" 0.0;
- inherit: "default" 0.0;
- image.normal: "sym_up_glow_normal.png";
- }
- description { state: "disabled" 0.0;
- inherit: "default" 0.0;
- image.normal: "sym_up_dark_normal.png";
- }
- }
- }
+ inherit: "efl/spin_button/inc_button";
+ images.image: "sym_up_light_normal.png" COMP;
+ images.image: "sym_up_glow_normal.png" COMP;
+ images.image: "sym_up_dark_normal.png" COMP;
+ parts {
+ part { name: "arrow.image";
+ scale: 1;
+ description { state: "default" 0.0;
+ min: 15 15;
+ max: 15 15;
+ image.normal: "sym_up_light_normal.png";
+ }
+ description { state: "pressed" 0.0;
+ inherit: "default" 0.0;
+ image.normal: "sym_up_glow_normal.png";
+ }
+ description { state: "disabled" 0.0;
+ inherit: "default" 0.0;
+ image.normal: "sym_up_dark_normal.png";
+ }
+ }
+ }
}
group { name: "efl/spin_button/dec_button:vertical";
- inherit: "efl/spin_button/dec_button";
- images.image: "sym_down_light_normal.png" COMP;
- images.image: "sym_down_glow_normal.png" COMP;
- images.image: "sym_down_dark_normal.png" COMP;
- parts {
- part { name: "arrow.image";
- scale: 1;
- description { state: "default" 0.0;
- min: 15 15;
- max: 15 15;
- image.normal: "sym_down_light_normal.png";
- }
- description { state: "pressed" 0.0;
- inherit: "default" 0.0;
- image.normal: "sym_down_glow_normal.png";
- }
- description { state: "disabled" 0.0;
- inherit: "default" 0.0;
- image.normal: "sym_down_dark_normal.png";
- }
+ inherit: "efl/spin_button/dec_button";
+ images.image: "sym_down_light_normal.png" COMP;
+ images.image: "sym_down_glow_normal.png" COMP;
+ images.image: "sym_down_dark_normal.png" COMP;
+ parts {
+ part { name: "arrow.image";
+ scale: 1;
+ description { state: "default" 0.0;
+ min: 15 15;
+ max: 15 15;
+ image.normal: "sym_down_light_normal.png";
+ }
+ description { state: "pressed" 0.0;
+ inherit: "default" 0.0;
+ image.normal: "sym_down_glow_normal.png";
+ }
+ description { state: "disabled" 0.0;
+ inherit: "default" 0.0;
+ image.normal: "sym_down_dark_normal.png";
+ }
+ }
+ }
+}
+
+group { "efl/spin_button/inc_button:picker";
+ inherit: "efl/spin_button/inc_button";
+ images.image: "sym_up_light_normal.png" COMP;
+ images.image: "sym_up_glow_normal.png" COMP;
+ images.image: "sym_up_dark_normal.png" COMP;
+ parts {
+ part { name: "arrow.image";
+ scale: 1;
+ description { state: "default" 0.0;
+ min: 15 15;
+ max: 15 15;
+ image.normal: "sym_up_light_normal.png";
+ }
+ description { state: "pressed" 0.0;
+ inherit: "default" 0.0;
+ image.normal: "sym_up_glow_normal.png";
+ }
+ description { state: "disabled" 0.0;
+ inherit: "default" 0.0;
+ image.normal: "sym_up_dark_normal.png";
}
}
}
+}
+
+group { "efl/spin_button/dec_button:picker";
+ inherit: "efl/spin_button/dec_button";
+ images.image: "sym_down_light_normal.png" COMP;
+ images.image: "sym_down_glow_normal.png" COMP;
+ images.image: "sym_down_dark_normal.png" COMP;
+ parts {
+ part { name: "arrow.image";
+ scale: 1;
+ description { state: "default" 0.0;
+ min: 15 15;
+ max: 15 15;
+ image.normal: "sym_down_light_normal.png";
+ }
+ description { state: "pressed" 0.0;
+ inherit: "default" 0.0;
+ image.normal: "sym_down_glow_normal.png";
+ }
+ description { state: "disabled" 0.0;
+ inherit: "default" 0.0;
+ image.normal: "sym_down_dark_normal.png";
+ }
+ }
+ }
+}
diff --git a/data/elementary/themes/edc/efl/timepicker.edc b/data/elementary/themes/edc/efl/timepicker.edc
new file mode 100644
index 0000000000..a1f030e8a4
--- /dev/null
+++ b/data/elementary/themes/edc/efl/timepicker.edc
@@ -0,0 +1,378 @@
+group { "efl/timepicker";
+ nomouse;
+ parts {
+ spacer { "base";
+ scale;
+ desc { "default";
+ min: 150 170;
+ }
+ desc { "24layout";
+ min: 110 170;
+ }
+ }
+ rect { "base_bg";
+ scale;
+ desc { "default";
+ rel.to: "base";
+ color: 0 0 0 35;
+ }
+ }
+ spacer { "padding_bg_top";
+ scale;
+ desc { "default";
+ min: 0 10;
+ max: -1 10;
+ fixed: 0 1;
+ rel1 {
+ relative: 0.0 0.0;
+ to: "base_bg";
+ }
+ rel2 {
+ relative: 1.0 0.0;
+ to: "base_bg";
+ }
+ align: 0.5 0.0;
+ }
+ }
+ spacer { "padding_bg_bottom";
+ scale;
+ desc { "default";
+ min: 0 10;
+ max: -1 10;
+ fixed: 0 1;
+ rel1 {
+ relative: 0.0 1.0;
+ to: "base_bg";
+ }
+ rel2 {
+ relative: 1.0 1.0;
+ to: "base_bg";
+ }
+ align: 0.5 1.0;
+ }
+ }
+ spacer { "bg";
+ scale;
+ desc { "default";
+ min: 150 150;
+ max: 150 150;
+ rel1 {
+ relative: 0.0 1.0;
+ to: "padding_bg_top";
+ }
+ rel2 {
+ relative: 1.0 0.0;
+ to: "padding_bg_bottom";
+ }
+ }
+ desc { "24layout";
+ inherit: "default";
+ min: 110 150;
+ max: 110 150;
+ }
+ }
+ spacer { "padding_left";
+ scale;
+ desc { "default";
+ min: 0 0;
+ max: 0 -1;
+ fixed: 1 0;
+ rel1 {
+ relative: 0.0 0.0;
+ to: "bg";
+ }
+ rel2 {
+ relative: 0.0 1.0;
+ to: "bg";
+ }
+ align: 0.0 0.0;
+ }
+ }
+ spacer { "padding_right";
+ scale;
+ desc { "default";
+ min: 0 0;
+ max: 0 -1;
+ fixed: 1 0;
+ rel1 {
+ relative: 1.0 0.0;
+ to: "bg";
+ }
+ rel2 {
+ relative: 1.0 1.0;
+ to: "bg";
+ }
+ align: 1.0 1.0;
+ }
+ }
+ swallow { "field0";
+ mouse;
+ scale;
+ desc { "default";
+ fixed: 1 0;
+ min: 40 0;
+ rel1 {
+ relative: 1.0 0.0;
+ to: "padding_left";
+ }
+ rel2.to: "padding_left";
+ align: 0.0 0.5;
+ }
+ }
+ spacer{ "padding_center1";
+ scale;
+ desc { "default";
+ fixed: 1 0;
+ min: 3 0;
+ max: 3 -1;
+ rel1 {
+ relative: 1.0 0.0;
+ to: "field0";
+ }
+ rel2.to: "field0";
+ align: 0.0 0.5;
+ }
+ desc { "invisible";
+ inherit: default 0.0;
+ min: 15 0;
+ max: 15 -1;
+ }
+ }
+ spacer { "bg_text";
+ scale;
+ desc { "default";
+ rel1 {
+ relative: 1.0 0.0;
+ to: "padding_center1";
+ }
+ rel2.to: "padding_center1";
+ align: 0.0 0.5;
+ min: 9 0;
+ max: 9 -1;
+ fixed: 1 0;
+ }
+ desc { "invisible";
+ inherit: default 0.0;
+ min: 0 0;
+ max: 0 0;
+ }
+ }
+ text { "hour_minute_colon";
+ scale;
+ desc { "default";
+ rel1.to: "bg_text";
+ rel2.to: "bg_text";
+ color: 255 255 255 255;
+ fixed: 1 1;
+ text {
+ min: 1 0;
+ font: "Sans";
+ size: "15";
+ //text: ":";
+ align: 0.5 0.44;
+ }
+ vis;
+ }
+ desc { "invisible";
+ inherit: default 0.0;
+ hid;
+ }
+ }
+ spacer { "padding_center2";
+ scale;
+ desc { "default";
+ fixed: 1 0;
+ min: 3 0;
+ max: 3 -1;
+ rel1 {
+ relative: 1.0 0.0;
+ to: "bg_text";
+ }
+ rel2.to: "bg_text";
+ align: 0.0 0.5;
+ }
+ desc { "invisible";
+ inherit: default 0.0;
+ min: 0 0;
+ max: 0 0;
+ }
+ }
+ swallow { "field1";
+ mouse;
+ scale;
+ desc { "default";
+ fixed: 1 0;
+ min: 40 0;
+ rel1 {
+ relative: 1.0 0.0;
+ to: "padding_center2";
+ }
+ rel2.to: "padding_center2";
+ align: 0.0 0.5;
+ }
+ }
+ spacer { "padding_center3";
+ scale;
+ desc { "default";
+ fixed: 1 0;
+ min: 3 0;
+ max: 3 -1;
+ rel1 {
+ relative: 1.0 0.0;
+ to: "field1";
+ }
+ rel2.to: "field1";
+ align: 0.0 0.5;
+ }
+ desc { "invisible";
+ inherit: default 0.0;
+ min: 15 0;
+ max: 15 -1;
+ }
+ }
+ spacer { "bg_text2";
+ scale;
+ desc { "default";
+ rel1 {
+ relative: 1.0 0.0;
+ to: "padding_center3";
+ }
+ rel2.to: "padding_center3";
+ align: 0.0 0.5;
+ min: 9 0;
+ max: 9 -1;
+ fixed: 1 0;
+ }
+ desc { "invisible";
+ inherit: default 0.0;
+ min: 0 0;
+ max: 0 0;
+ }
+ }
+ text { "hour_minute_colon2";
+ scale;
+ desc { "default";
+ rel1.to: "bg_text2";
+ rel2.to: "bg_text2";
+ color: 255 255 255 255;
+ fixed: 1 1;
+ text {
+ min: 1 0;
+ font: "Sans";
+ size: "15";
+ //text: ":";
+ align: 0.5 0.44;
+ }
+ vis;
+ }
+ desc { "invisible";
+ inherit: default 0.0;
+ hid;
+ }
+ }
+ spacer { "padding_center4";
+ scale;
+ desc { "default";
+ fixed: 1 0;
+ min: 3 0;
+ max: 3 -1;
+ rel1 {
+ relative: 1.0 0.0;
+ to: "bg_text2";
+ }
+ rel2.to: "bg_text2";
+ align: 0.0 0.5;
+ }
+ desc { "invisible";
+ inherit: default 0.0;
+ min: 0 0;
+ max: 0 0;
+ }
+ }
+ swallow { "field2";
+ mouse;
+ scale;
+ desc { "default";
+ fixed: 1 0;
+ min: 40 0;
+ max: 40 -1;
+ rel1 {
+ relative: 1.0 0.0;
+ to: "padding_center4";
+ }
+ rel2.to: "padding_center4";
+ align: 0.0 0.5;
+ }
+ desc { "24layout";
+ hid;
+ min: 0 0;
+ max: 0 -1;
+ }
+ }
+ rect { "access";
+ repeat;
+ desc { "default";
+ fixed: 1 1;
+ rel1.to: "bg";
+ rel2.to: "bg";
+ color: 0 0 0 0;
+ }
+ }
+ }
+ programs {
+ program { "visible_ampm";
+ signal: "elm,state,ampm,visible";
+ source: "elm";
+ script {
+ set_state(PART:"base", "default", 0.0);
+ set_state(PART:"bg", "default", 0.0);
+ set_state(PART:"field2", "default", 0.0);
+ }
+ }
+ program { "invisible_ampm";
+ signal: "elm,state,ampm,invisible";
+ source: "elm";
+ script {
+ set_state(PART:"base", "24layout", 0.0);
+ set_state(PART:"bg", "24layout", 0.0);
+ set_state(PART:"field2", "24layout", 0.0);
+ }
+ }
+ program { "visible_colon_field0";
+ signal: "elm,state,colon,visible,field0";
+ source: "elm";
+ action: STATE_SET "default";
+ target: "padding_center1";
+ target: "hour_minute_colon";
+ target: "bg_text";
+ target: "padding_center2";
+ }
+ program { "invisible_colon_field0";
+ signal: "elm,state,colon,invisible,field0";
+ source: "elm";
+ action: STATE_SET "invisible";
+ target: "padding_center1";
+ target: "hour_minute_colon";
+ target: "bg_text";
+ target: "padding_center2";
+ }
+ program { "visible_colon_field1";
+ signal: "elm,state,colon,visible,field1";
+ source: "elm";
+ action: STATE_SET "default";
+ target: "padding_center3";
+ target: "hour_minute_colon2";
+ target: "bg_text2";
+ target: "padding_center4";
+ }
+ program { "invisible_colon_field1";
+ signal: "elm,state,colon,invisible,field1";
+ source: "elm";
+ action: STATE_SET "invisible";
+ target: "padding_center3";
+ target: "hour_minute_colon2";
+ target: "bg_text2";
+ target: "padding_center4";
+ }
+ }
+}
diff --git a/data/elementary/themes/edc/elm/button.edc b/data/elementary/themes/edc/elm/button.edc
index c5c48d3a21..1d0064765b 100644
--- a/data/elementary/themes/edc/elm/button.edc
+++ b/data/elementary/themes/edc/elm/button.edc
@@ -1783,6 +1783,30 @@ group { name: "elm/button/base/hoversel_horizontal_entry/default";
}
}
}
+
+ group { name: "elm/button/base/spinner/increase/picker";
+ inherit: "elm/button/base/spinner/increase/vertical";
+ parts {
+ part { name: "arrow.image";
+ description { state: "default" 0.0;
+ min: 20 20;
+ max: 20 20;
+ }
+ }
+ }
+ }
+
+ group { name: "elm/button/base/spinner/decrease/picker";
+ inherit: "elm/button/base/spinner/decrease/vertical";
+ parts {
+ part { name: "arrow.image";
+ description { state: "default" 0.0;
+ min: 20 20;
+ max: 20 20;
+ }
+ }
+ }
+ }
/******************* SPINNER BUTTONS STYLES END **********************/
group { name: "elm/button/base/combobox_vertical/default";
alias: "elm/button/base/combobox_vertical/entry";
diff --git a/data/elementary/themes/edc/elm/entry.edc b/data/elementary/themes/edc/elm/entry.edc
index 189bf968d7..0a806a6901 100644
--- a/data/elementary/themes/edc/elm/entry.edc
+++ b/data/elementary/themes/edc/elm/entry.edc
@@ -854,6 +854,7 @@ group { name: "elm/entry/base-single/default";
group { name: "elm/entry/base-single/spinner/default";
alias: "elm/entry/base-single/spinner/vertical";
+ alias: "elm/entry/base-single/spinner/picker";
alias: "elm/entry/base-single/spin_button/default";
alias: "elm/entry/base-single/spin_button/vertical";
inherit: "elm/entry/base-single/default";
diff --git a/src/Makefile_Efl.am b/src/Makefile_Efl.am
index f98f554362..6f9c3fc9c9 100644
--- a/src/Makefile_Efl.am
+++ b/src/Makefile_Efl.am
@@ -75,6 +75,9 @@ efl_eolian_files = \
lib/efl/interfaces/efl_ui_menu.eo \
lib/efl/interfaces/efl_ui_autorepeat.eo \
lib/efl/interfaces/efl_ui_format.eo \
+ lib/efl/interfaces/efl_ui_datetime.eo \
+ lib/efl/interfaces/efl_ui_date.eo \
+ lib/efl/interfaces/efl_ui_time.eo \
lib/efl/interfaces/efl_gfx_color_class.eo \
lib/efl/interfaces/efl_gfx_text_class.eo \
lib/efl/interfaces/efl_gfx_size_class.eo \
@@ -128,6 +131,7 @@ lib/efl/interfaces/efl_io_queue.c \
lib/efl/interfaces/efl_observer.c \
lib/efl/interfaces/efl_file.c \
lib/efl/interfaces/efl_ui_format.c \
+lib/efl/interfaces/efl_ui_datetime.c \
lib/efl/interfaces/efl_gfx_color.c \
lib/efl/interfaces/efl_text_markup_util.c \
$(NULL)
diff --git a/src/Makefile_Elementary.am b/src/Makefile_Elementary.am
index 02008ee6e1..cbfdeda975 100644
--- a/src/Makefile_Elementary.am
+++ b/src/Makefile_Elementary.am
@@ -23,6 +23,8 @@ elm_public_eolian_files = \
lib/elementary/efl_ui_slider_interval.eo \
lib/elementary/efl_ui_spin.eo \
lib/elementary/efl_ui_spin_button.eo \
+ lib/elementary/efl_ui_datepicker.eo \
+ lib/elementary/efl_ui_timepicker.eo \
lib/elementary/efl_ui_video.eo \
lib/elementary/efl_ui_win.eo \
lib/elementary/efl_ui_win_inlined.eo \
@@ -370,6 +372,8 @@ includesunstable_HEADERS = \
lib/elementary/elm_widget_spinner.h \
lib/elementary/efl_ui_spin_private.h \
lib/elementary/efl_ui_spin_button_private.h \
+ lib/elementary/efl_ui_datepicker_private.h \
+ lib/elementary/efl_ui_timepicker_private.h \
lib/elementary/elm_widget_table.h \
lib/elementary/elm_widget_thumb.h \
lib/elementary/elm_widget_toolbar.h \
@@ -722,6 +726,8 @@ lib_elementary_libelementary_la_SOURCES = \
lib/elementary/efl_ui_slider_interval.c \
lib/elementary/efl_ui_spin.c \
lib/elementary/efl_ui_spin_button.c \
+ lib/elementary/efl_ui_datepicker.c \
+ lib/elementary/efl_ui_timepicker.c \
lib/elementary/elm_slideshow.c \
lib/elementary/elm_spinner.c \
lib/elementary/elm_store.c \
@@ -974,6 +980,8 @@ bin/elementary/test_ui_slider.c \
bin/elementary/test_ui_slider_interval.c \
bin/elementary/test_ui_spin.c \
bin/elementary/test_ui_spin_button.c \
+bin/elementary/test_ui_datepicker.c \
+bin/elementary/test_ui_timepicker.c \
bin/elementary/test_slideshow.c \
bin/elementary/test_spinner.c \
bin/elementary/test_store.c \
diff --git a/src/bin/elementary/Makefile.am b/src/bin/elementary/Makefile.am
index 0749293876..57c6035b79 100644
--- a/src/bin/elementary/Makefile.am
+++ b/src/bin/elementary/Makefile.am
@@ -133,6 +133,8 @@ test_slideshow.c \
test_spinner.c \
test_ui_spinner.c \
test_ui_buttonspin.c \
+test_ui_datepicker.c \
+test_ui_timepicker.c \
test_store.c \
test_sys_notify.c \
test_systray.c \
diff --git a/src/bin/elementary/test.c b/src/bin/elementary/test.c
index 9862d1d906..81676a080e 100644
--- a/src/bin/elementary/test.c
+++ b/src/bin/elementary/test.c
@@ -183,6 +183,8 @@ void test_efl_ui_scroller2(void *data, Evas_Object *obj, void *event_info);
void test_spinner(void *data, Evas_Object *obj, void *event_info);
void test_ui_spin(void *data, Evas_Object *obj, void *event_info);
void test_ui_spin_button(void *data, Evas_Object *obj, void *event_info);
+void test_ui_datepicker(void *data, Evas_Object *obj, void *event_info);
+void test_ui_timepicker(void *data, Evas_Object *obj, void *event_info);
void test_index(void *data, Evas_Object *obj, void *event_info);
void test_index2(void *data, Evas_Object *obj, void *event_info);
void test_index3(void *data, Evas_Object *obj, void *event_info);
@@ -1083,6 +1085,8 @@ add_tests:
ADD_TEST(NULL, "Times & Dates", "Datetime", test_datetime);
ADD_TEST_EO(NULL, "Times & Dates", "Efl.Ui.Calendar", test_efl_ui_calendar);
ADD_TEST_EO(NULL, "Times & Dates", "Efl.Ui.Clock", test_ui_clock);
+ ADD_TEST_EO(NULL, "Times & Dates", "Efl.Ui.Datepicker", test_ui_datepicker);
+ ADD_TEST_EO(NULL, "Times & Dates", "Efl.Ui.Timepicker", test_ui_timepicker);
//------------------------------//
ADD_TEST(NULL, "Text", "Label", test_label);
diff --git a/src/bin/elementary/test_ui_datepicker.c b/src/bin/elementary/test_ui_datepicker.c
new file mode 100644
index 0000000000..219ed2ee2b
--- /dev/null
+++ b/src/bin/elementary/test_ui_datepicker.c
@@ -0,0 +1,37 @@
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#endif
+#include <Elementary.h>
+
+static void
+_date_changed_cb(void *data EINA_UNUSED, const Efl_Event *ev)
+{
+ int year, month, day;
+
+ efl_ui_date_get(ev->object, &year, &month, &day);
+ printf("Current date is %d %d %d\n", year, month, day);
+}
+
+void
+test_ui_datepicker(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
+{
+ Eo *win, *bx;
+
+ win = efl_add(EFL_UI_WIN_CLASS, efl_main_loop_get(),
+ efl_ui_win_type_set(efl_added, EFL_UI_WIN_BASIC),
+ efl_text_set(efl_added, "Efl.Ui.Datepicker"),
+ efl_ui_win_autodel_set(efl_added, EINA_TRUE));
+
+ bx = efl_add(EFL_UI_BOX_CLASS, win,
+ efl_content_set(win, efl_added),
+ efl_ui_direction_set(efl_added, EFL_UI_DIR_DOWN));
+
+ efl_add(EFL_UI_DATEPICKER_CLASS, bx,
+ efl_ui_date_set(efl_added, 1987, 9, 17),
+ efl_ui_date_max_set(efl_added, 1985, 6, 7),
+ efl_ui_date_min_set(efl_added, 1980, 6, 7),
+ efl_event_callback_add(efl_added, EFL_UI_DATEPICKER_EVENT_CHANGED,_date_changed_cb, NULL),
+ efl_pack(bx, efl_added));
+
+ efl_gfx_size_set(win, EINA_SIZE2D(150, 170));
+}
diff --git a/src/bin/elementary/test_ui_timepicker.c b/src/bin/elementary/test_ui_timepicker.c
new file mode 100644
index 0000000000..bbf373a740
--- /dev/null
+++ b/src/bin/elementary/test_ui_timepicker.c
@@ -0,0 +1,36 @@
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#endif
+#include <Elementary.h>
+
+static void
+_time_changed_cb(void *data EINA_UNUSED, const Efl_Event *ev)
+{
+ int hour, min;
+
+ efl_ui_time_get(ev->object, &hour, &min);
+ printf("Current time is %d %d\n", hour, min);
+}
+
+
+void
+test_ui_timepicker(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
+{
+ Eo *win, *bx;
+
+ win = efl_add(EFL_UI_WIN_CLASS, efl_main_loop_get(),
+ efl_ui_win_type_set(efl_added, EFL_UI_WIN_BASIC),
+ efl_text_set(efl_added, "Efl.Ui.Timepicker"),
+ efl_ui_win_autodel_set(efl_added, EINA_TRUE));
+
+ bx = efl_add(EFL_UI_BOX_CLASS, win,
+ efl_content_set(win, efl_added),
+ efl_ui_direction_set(efl_added, EFL_UI_DIR_DOWN));
+
+ efl_add(EFL_UI_TIMEPICKER_CLASS, bx,
+ efl_ui_time_set(efl_added, 11, 35),
+ efl_event_callback_add(efl_added, EFL_UI_TIMEPICKER_EVENT_CHANGED,_time_changed_cb, NULL),
+ efl_pack(bx, efl_added));
+
+ efl_gfx_size_set(win, EINA_SIZE2D(150, 170));
+}
diff --git a/src/lib/efl/CMakeLists.txt b/src/lib/efl/CMakeLists.txt
index 909cea5b5b..ba8f0a7016 100644
--- a/src/lib/efl/CMakeLists.txt
+++ b/src/lib/efl/CMakeLists.txt
@@ -53,6 +53,8 @@ set(PUBLIC_EO_FILES
interfaces/efl_ui_item.eo
interfaces/efl_ui_menu.eo
interfaces/efl_ui_range.eo
+ interfaces/efl_ui_date.eo
+ interfaces/efl_ui_time.eo
interfaces/efl_ui_autorepeat.eo
interfaces/efl_vpath.eo
interfaces/efl_vpath_core.eo
diff --git a/src/lib/efl/Efl.h b/src/lib/efl/Efl.h
index 2399c9c30b..1909a0e283 100644
--- a/src/lib/efl/Efl.h
+++ b/src/lib/efl/Efl.h
@@ -95,6 +95,8 @@ typedef Efl_Gfx_Path_Command_Type Efl_Gfx_Path_Command;
#include "interfaces/efl_ui_scrollable_interactive.eo.h"
#include "interfaces/efl_ui_selectable.eo.h"
#include "interfaces/efl_ui_zoom.eo.h"
+#include "interfaces/efl_ui_date.eo.h"
+#include "interfaces/efl_ui_time.eo.h"
#include "interfaces/efl_screen.eo.h"
@@ -136,6 +138,7 @@ typedef Efl_Gfx_Path_Command_Type Efl_Gfx_Path_Command;
#include "interfaces/efl_ui_model_connect.eo.h"
#include "interfaces/efl_ui_factory.eo.h"
#include "interfaces/efl_ui_format.eo.h"
+#include "interfaces/efl_ui_datetime.eo.h"
/* Observable interface */
#include "interfaces/efl_observer.eo.h"
diff --git a/src/lib/efl/interfaces/efl_interfaces_main.c b/src/lib/efl/interfaces/efl_interfaces_main.c
index cb1738e52b..c7742fe39b 100644
--- a/src/lib/efl/interfaces/efl_interfaces_main.c
+++ b/src/lib/efl/interfaces/efl_interfaces_main.c
@@ -77,6 +77,8 @@
#include "interfaces/efl_ui_scrollbar.eo.c"
#include "interfaces/efl_ui_selectable.eo.c"
#include "interfaces/efl_ui_zoom.eo.c"
+#include "interfaces/efl_ui_date.eo.c"
+#include "interfaces/efl_ui_time.eo.c"
EAPI void
__efl_internal_init(void)
diff --git a/src/lib/efl/interfaces/efl_ui_date.eo b/src/lib/efl/interfaces/efl_ui_date.eo
new file mode 100644
index 0000000000..74d938ff39
--- /dev/null
+++ b/src/lib/efl/interfaces/efl_ui_date.eo
@@ -0,0 +1,63 @@
+interface Efl.Ui.Date
+{
+ [[Efl UI date interface]]
+ methods {
+ @property min {
+ [[The lower boundary of date.
+
+ Year: years since 1900. Negative value represents year below 1900
+ (year value -30 represents 1870). Year default range is from 70
+ to 137.
+
+ Month: default value range is from 0 to 11.
+
+ Day: default value range is from 1 to 31 according to the month
+ value.
+ ]]
+ set {} get{}
+ values {
+ year: int; [[The year value.]]
+ month: int; [[The month value.]]
+ day: int; [[The day value.]]
+ }
+ }
+ @property max {
+ [[The upper boundary of date.
+
+ Year: years since 1900. Negative value represents year below 1900
+ (year value -30 represents 1870). Year default range is from 70
+ to 137.
+
+ Month: default value range is from 0 to 11.
+
+ Day: default value range is from 1 to 31 according to the month
+ value.
+ ]]
+ set {} get{}
+ values {
+ year: int; [[The year value.]]
+ month: int; [[The month value.]]
+ day: int; [[The day value.]]
+ }
+ }
+ @property date {
+ [[The current value of date.
+
+ Year: years since 1900. Negative value represents year below 1900
+ (year value -30 represents 1870). Year default range is from 70
+ to 137.
+
+ Month: default value range is from 0 to 11.
+
+ Day: default value range is from 1 to 31 according to the month
+ value.
+ ]]
+ set {} get{}
+ values {
+ year: int; [[The year value.]]
+ month: int; [[The month value.]]
+ day: int; [[The day value.]]
+ }
+ }
+ }
+}
diff --git a/src/lib/efl/interfaces/efl_ui_datetime.c b/src/lib/efl/interfaces/efl_ui_datetime.c
new file mode 100644
index 0000000000..afec3abe5e
--- /dev/null
+++ b/src/lib/efl/interfaces/efl_ui_datetime.c
@@ -0,0 +1,176 @@
+#include <config.h>
+#include "Efl.h"
+
+#ifdef HAVE_LANGINFO_H
+# include <langinfo.h>
+#endif
+
+#define ERR(...) EINA_LOG_DOM_ERR(EINA_LOG_DOMAIN_DEFAULT, __VA_ARGS__)
+#define DBG(...) EINA_LOG_DOM_DBG(EINA_LOG_DOMAIN_DEFAULT, __VA_ARGS__)
+
+#define MAX_FORMAT_LEN 32
+
+static const char *multifield_formats = "cxXrRTDF";
+
+typedef struct
+{
+ Efl_Time time;
+ char format[MAX_FORMAT_LEN];
+} Efl_Ui_Datetime_Data;
+
+Eina_Bool init = EINA_FALSE;
+
+static void
+_time_init(Efl_Time *curr_time)
+{
+ time_t t;
+
+ t = time(NULL);
+ localtime_r(&t, curr_time);
+
+ init = EINA_TRUE;
+}
+
+static char *
+_expanded_fmt_str_get(char ch)
+{
+ char *exp_fmt = "";
+ switch (ch)
+ {
+ case 'c':
+#if defined(HAVE_LANGINFO_H) || defined (_WIN32)
+ exp_fmt = nl_langinfo(D_T_FMT);
+#else
+ exp_fmt = "";
+#endif
+ break;
+
+ case 'x':
+#if defined(HAVE_LANGINFO_H) || defined (_WIN32)
+ exp_fmt = nl_langinfo(D_FMT);
+#else
+ exp_fmt = "";
+#endif
+ break;
+
+ case 'X':
+#if defined(HAVE_LANGINFO_H) || defined (_WIN32)
+ exp_fmt = nl_langinfo(T_FMT);
+#else
+ exp_fmt = "";
+#endif
+ break;
+
+ case 'r':
+#if defined(HAVE_LANGINFO_H) || defined (_WIN32)
+ exp_fmt = nl_langinfo(T_FMT_AMPM);
+#else
+ exp_fmt = "";
+#endif
+ break;
+
+ case 'R':
+ exp_fmt = "%H:%M";
+ break;
+
+ case 'T':
+ exp_fmt = "%H:%M:%S";
+ break;
+
+ case 'D':
+ exp_fmt = "%m/%d/%y";
+ break;
+
+ case 'F':
+ exp_fmt = "%Y-%m-%d";
+ break;
+
+ default:
+ exp_fmt = "";
+ break;
+ }
+
+ return exp_fmt;
+}
+
+static void
+_expand_format(char *dt_fmt)
+{
+ char *ptr, *expanded_fmt, ch;
+ unsigned int idx, len = 0;
+ char buf[MAX_FORMAT_LEN] = {0, };
+ Eina_Bool fmt_char, fmt_expanded;
+
+ do {
+ idx = 0;
+ fmt_char = EINA_FALSE;
+ fmt_expanded = EINA_FALSE;
+ ptr = dt_fmt;
+ while ((ch = *ptr))
+ {
+ if ((fmt_char) && (strchr(multifield_formats, ch)))
+ {
+ /* replace the multi-field format characters with
+ * corresponding expanded format */
+ expanded_fmt = _expanded_fmt_str_get(ch);
+ len = strlen(expanded_fmt);
+ if (len > 0) fmt_expanded = EINA_TRUE;
+ buf[--idx] = 0;
+ strncat(buf, expanded_fmt, len);
+ idx += len;
+ }
+ else buf[idx++] = ch;
+
+ if (ch == '%') fmt_char = EINA_TRUE;
+ else fmt_char = EINA_FALSE;
+
+ ptr++;
+ }
+
+ buf[idx] = 0;
+ strncpy(dt_fmt, buf, MAX_FORMAT_LEN);
+ } while (fmt_expanded);
+}
+
+EOLIAN static void
+_efl_ui_datetime_datetime_value_set(Eo *obj, Efl_Ui_Datetime_Data *sd, Efl_Time newtime)
+{
+ sd->time = newtime;
+}
+
+EOLIAN static Efl_Time
+_efl_ui_datetime_datetime_value_get(Eo *obj EINA_UNUSED, Efl_Ui_Datetime_Data *sd)
+{
+ if (!init) _time_init(&sd->time);
+
+ return sd->time;
+}
+
+EOLIAN static void
+_efl_ui_datetime_datetime_format_set(Eo *obj, Efl_Ui_Datetime_Data *sd, const char *fmt)
+{
+ //Is this needed?
+}
+
+EOLIAN static const char *
+_efl_ui_datetime_datetime_format_get(Eo *obj EINA_UNUSED, Efl_Ui_Datetime_Data *sd)
+{
+#if defined(HAVE_LANGINFO_H) || defined (_WIN32)
+ strncpy(sd->format, nl_langinfo(D_T_FMT), MAX_FORMAT_LEN);
+#else
+ strncpy(sd->format, "", MAX_FORMAT_LEN);
+#endif
+ sd->format[MAX_FORMAT_LEN - 1] = '\0';
+
+ _expand_format(sd->format);
+
+ return sd->format;
+}
+EOLIAN static const char *
+_efl_ui_datetime_datetime_string_get(Eo *obj EINA_UNUSED, Efl_Ui_Datetime_Data *sd EINA_UNUSED, const char *fmt EINA_UNUSED)
+{
+ //TODO: strftime on upsteam, icu module connect here on tizen.
+ return NULL;
+}
+#include "interfaces/efl_ui_datetime.eo.c"
+
diff --git a/src/lib/efl/interfaces/efl_ui_datetime.eo b/src/lib/efl/interfaces/efl_ui_datetime.eo
new file mode 100644
index 0000000000..9ffc054808
--- /dev/null
+++ b/src/lib/efl/interfaces/efl_ui_datetime.eo
@@ -0,0 +1,38 @@
+import efl_types;
+
+mixin Efl.Ui.Datetime
+{
+ [[interface class for Date/time picker]]
+ methods {
+ @property datetime_value {
+ [[The value of a date, time.
+
+ The year, month, day values for date picker, hour, min values for
+ time picker.
+ ]]
+ values {
+ newtime: Efl.Time; [[Time structure containing the date, time value.]]
+ }
+ }
+ @property datetime_format {
+ [[The date, time format.
+
+ Default format is taken as per the system locale settings.
+ ]]
+ values {
+ fmt: string; [[The format string]]
+ }
+ }
+ @property datetime_string {
+ get {
+ [[Get the string that matches with the format.]]
+ }
+ keys {
+ fmt: string; [[The format string]]
+ }
+ values {
+ string: string; [[The format string]]
+ }
+ }
+ }
+}
diff --git a/src/lib/efl/interfaces/efl_ui_time.eo b/src/lib/efl/interfaces/efl_ui_time.eo
new file mode 100644
index 0000000000..3565a695b6
--- /dev/null
+++ b/src/lib/efl/interfaces/efl_ui_time.eo
@@ -0,0 +1,19 @@
+interface Efl.Ui.Time
+{
+ [[Efl UI Time class]]
+ methods {
+ @property time {
+ [[The current value of time
+
+ Hour: The value will be in terms of 24 hr format (0~23)
+
+ Minute: The range is from 0 to 59.
+ ]]
+ set {} get{}
+ values {
+ hour: int; [[The hour value.]]
+ min: int; [[The minute value.]]
+ }
+ }
+ }
+}
diff --git a/src/lib/elementary/Elementary.h b/src/lib/elementary/Elementary.h
index a7161e4a9c..d832a4d08e 100644
--- a/src/lib/elementary/Elementary.h
+++ b/src/lib/elementary/Elementary.h
@@ -319,6 +319,8 @@ typedef Eo Efl_Ui_Focus_Manager;
# include <efl_ui_clock.eo.h>
# include <efl_ui_spin.eo.h>
# include <efl_ui_spin_button.eo.h>
+# include <efl_ui_datepicker.eo.h>
+# include <efl_ui_timepicker.eo.h>
# include <efl_ui_image_factory.eo.h>
# include <efl_ui_slider_interval.eo.h>
# include <efl_ui_layout_factory.eo.h>
diff --git a/src/lib/elementary/efl_ui_datepicker.c b/src/lib/elementary/efl_ui_datepicker.c
new file mode 100644
index 0000000000..19555d5c3b
--- /dev/null
+++ b/src/lib/elementary/efl_ui_datepicker.c
@@ -0,0 +1,352 @@
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#endif
+
+#include <Elementary.h>
+
+#include "elm_priv.h"
+#include "efl_ui_datepicker_private.h"
+
+#define MY_CLASS EFL_UI_DATEPICKER_CLASS
+
+#define MY_CLASS_NAME "Efl.Ui.Datepicker"
+
+#define FMT_LEN_MAX 32
+
+#define DATE_GET(obj) \
+ do { \
+ Efl_Time t = efl_ui_datetime_value_get(obj); \
+ sd->cur_date[DATEPICKER_YEAR] = t.tm_year + 1900; \
+ sd->cur_date[DATEPICKER_MONTH] = t.tm_mon + 1; \
+ sd->cur_date[DATEPICKER_DAY] = t.tm_mday; \
+ } while (0)
+
+#define DATE_SET(obj) \
+ do { \
+ Efl_Time t; \
+ t.tm_year = sd->cur_date[DATEPICKER_YEAR] - 1900; \
+ t.tm_mon = sd->cur_date[DATEPICKER_MONTH] - 1; \
+ t.tm_mday = sd->cur_date[DATEPICKER_DAY]; \
+ efl_ui_datetime_value_set(obj, t); \
+ } while (0)
+
+static const char *fmt_char[] = {"Yy", "mbBh", "de"};
+
+static Eina_Bool
+_validate_params(int year, int month, int day)
+{
+ if (year < 1900 || year > 2037 || month < 1 || month > 12 || day < 0 || day > 31)
+ return EINA_FALSE;
+ else return EINA_TRUE;
+}
+
+static Eina_Bool
+_date_cmp(int time1[], int time2[])
+{
+ unsigned int idx;
+
+ for (idx = 0; idx < EFL_UI_DATEPICKER_TYPE_COUNT; idx++)
+ {
+ if (time1[idx] != time2[idx])
+ return EINA_FALSE;
+ }
+
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_validate_date_limits(int time1[], int time2[], Eina_Bool swap)
+{
+ unsigned int idx;
+ int *t1, *t2;
+
+ t1 = (swap) ? time2 : time1;
+ t2 = (swap) ? time1 : time2;
+
+ for (idx = 0; idx < EFL_UI_DATEPICKER_TYPE_COUNT; idx++)
+ {
+ if (time1[idx] < time2[idx])
+ {
+ memcpy(t1, t2, (sizeof(int) * EFL_UI_DATEPICKER_TYPE_COUNT));
+ return EINA_TRUE;
+ }
+ else if (time1[idx] > time2[idx])
+ return EINA_FALSE;
+ }
+
+ return EINA_FALSE;
+}
+
+static int
+_max_days_get(int year, int month)
+{
+ struct tm time1;
+ time_t t;
+ int day;
+
+ t = time(NULL);
+ localtime_r(&t, &time1);
+ time1.tm_year = year;
+ time1.tm_mon = month;
+ for (day = 28; day <= 31;
+ day++)
+ {
+ time1.tm_mday = day;
+ mktime(&time1);
+ /* To restrict month wrapping because of summer time in some locales,
+ * ignore day light saving mode in mktime(). */
+ time1.tm_isdst = -1;
+ if (time1.tm_mday == 1) break;
+ }
+ day--;
+
+ return day;
+}
+
+static void
+_field_value_update(Eo *obj)
+{
+ Efl_Ui_Datepicker_Data *sd = efl_data_scope_get(obj, MY_CLASS);
+
+ efl_ui_range_value_set(sd->year, sd->cur_date[DATEPICKER_YEAR]);
+ efl_ui_range_value_set(sd->month, sd->cur_date[DATEPICKER_MONTH]);
+ efl_ui_range_value_set(sd->day, sd->cur_date[DATEPICKER_DAY]);
+
+ DATE_SET(obj);
+}
+
+static void
+_field_changed_cb(void *data, const Efl_Event *ev)
+{
+ int max_day;
+
+ Efl_Ui_Datepicker_Data *sd = efl_data_scope_get(data, MY_CLASS);
+
+ if (ev->object == sd->year)
+ sd->cur_date[DATEPICKER_YEAR] = efl_ui_range_value_get(sd->year);
+ else if (ev->object == sd->month)
+ sd->cur_date[DATEPICKER_MONTH] = efl_ui_range_value_get(sd->month);
+ else
+ sd->cur_date[DATEPICKER_DAY] = efl_ui_range_value_get(sd->day);
+
+ if (!(ev->object == sd->day))
+ {
+ max_day = _max_days_get(sd->cur_date[DATEPICKER_YEAR], sd->cur_date[DATEPICKER_MONTH]);
+ efl_ui_range_min_max_set(sd->day, 1, max_day);
+ }
+
+ if (_validate_date_limits(sd->cur_date, sd->min_date, EINA_FALSE) ||
+ _validate_date_limits(sd->max_date, sd->cur_date, EINA_TRUE))
+ {
+ _field_value_update(data);
+ return;
+ }
+
+ DATE_SET(data);
+ efl_event_callback_call(data, EFL_UI_DATEPICKER_EVENT_CHANGED, NULL);
+}
+
+static void
+_fields_init(Eo *obj)
+{
+ const char *fmt;
+ char ch;
+ int i;
+ int field = 0;
+ char buf[FMT_LEN_MAX];
+
+ Efl_Ui_Datepicker_Data *sd = efl_data_scope_get(obj, MY_CLASS);
+
+ //Field create.
+ sd->year = efl_add(EFL_UI_SPIN_BUTTON_CLASS, obj,
+ efl_ui_range_min_max_set(efl_added, 1970, 2037),
+ efl_ui_spin_button_circulate_set(efl_added, EINA_TRUE),
+ efl_ui_spin_button_editable_set(efl_added, EINA_TRUE),
+ efl_event_callback_add(efl_added, EFL_UI_SPIN_EVENT_CHANGED,_field_changed_cb, obj),
+ elm_object_style_set(efl_added, "picker"));
+
+ sd->month = efl_add(EFL_UI_SPIN_BUTTON_CLASS, obj,
+ efl_ui_range_min_max_set(efl_added, 1, 12),
+ efl_ui_spin_button_circulate_set(efl_added, EINA_TRUE),
+ efl_ui_spin_button_editable_set(efl_added, EINA_TRUE),
+ efl_event_callback_add(efl_added, EFL_UI_SPIN_EVENT_CHANGED,_field_changed_cb, obj),
+ elm_object_style_set(efl_added, "picker"));
+
+ sd->day = efl_add(EFL_UI_SPIN_BUTTON_CLASS, obj,
+ efl_ui_range_min_max_set(efl_added, 1, 31),
+ efl_ui_spin_button_circulate_set(efl_added, EINA_TRUE),
+ efl_ui_spin_button_editable_set(efl_added, EINA_TRUE),
+ efl_event_callback_add(efl_added, EFL_UI_SPIN_EVENT_CHANGED,_field_changed_cb, obj),
+ elm_object_style_set(efl_added, "picker"));
+
+ DATE_GET(obj);
+ //Using system config?
+ sd->min_date[DATEPICKER_YEAR] = 1970;
+ sd->min_date[DATEPICKER_MONTH] = 1;
+ sd->min_date[DATEPICKER_DAY] = 1;
+ sd->max_date[DATEPICKER_YEAR] = 2037;
+ sd->max_date[DATEPICKER_MONTH] = 12;
+ sd->max_date[DATEPICKER_DAY] = 31;
+
+ _field_value_update(obj);
+
+ fmt = efl_ui_datetime_format_get(obj);
+ if (!fmt)
+ {
+ ERR("Failed to get current format.");
+ //Gives default format when the gets format failed.
+ fmt = "%Y %b %d";
+ }
+
+ //Sort fields by format.
+ while((ch = *fmt))
+ {
+ //TODO: ignore extensions and separators.
+ for (i = 0; i < EFL_UI_DATEPICKER_TYPE_COUNT; i++)
+ {
+ if (strchr(fmt_char[i], ch))
+ {
+ snprintf(buf, sizeof(buf), "field%d", field++);
+ if (i == DATEPICKER_YEAR)
+ efl_content_set(efl_part(obj, buf), sd->year);
+ else if (i == DATEPICKER_MONTH)
+ efl_content_set(efl_part(obj, buf), sd->month);
+ else
+ efl_content_set(efl_part(obj, buf), sd->day);
+
+ break;
+ }
+ }
+ fmt++;
+ }
+}
+
+EOLIAN static void
+_efl_ui_datepicker_elm_layout_sizing_eval(Eo *obj, Efl_Ui_Datepicker_Data *_pd EINA_UNUSED)
+{
+ Evas_Coord minw = -1, minh = -1;
+ ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
+
+ elm_coords_finger_size_adjust(1, &minw, 1, &minh);
+ edje_object_size_min_restricted_calc
+ (wd->resize_obj, &minw, &minh, minw, minh);
+ elm_coords_finger_size_adjust(1, &minw, 1, &minh);
+ evas_object_size_hint_min_set(obj, minw, minh);
+ evas_object_size_hint_max_set(obj, -1, -1);
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_datepicker_efl_ui_widget_widget_event(Eo *obj, Efl_Ui_Datepicker_Data *sd, const Efl_Event *eo_event, Evas_Object *src EINA_UNUSED)
+{
+ return EINA_TRUE;
+}
+
+EOLIAN static Eo *
+_efl_ui_datepicker_efl_object_constructor(Eo *obj, Efl_Ui_Datepicker_Data *sd)
+{
+ ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, NULL);
+
+ if (!elm_widget_theme_klass_get(obj))
+ elm_widget_theme_klass_set(obj, "datepicker");
+ obj = efl_constructor(efl_super(obj, MY_CLASS));
+
+ if (!elm_widget_theme_object_set(obj, wd->resize_obj,
+ elm_widget_theme_klass_get(obj),
+ elm_widget_theme_element_get(obj),
+ elm_widget_theme_style_get(obj)))
+ CRI("Failed to set layout!");
+
+ _fields_init(obj);
+
+ elm_widget_sub_object_parent_add(obj);
+
+ elm_widget_can_focus_set(obj, EINA_TRUE);
+
+ return obj;
+}
+
+EOLIAN static void
+_efl_ui_datepicker_efl_object_destructor(Eo *obj, Efl_Ui_Datepicker_Data *sd EINA_UNUSED)
+{
+ efl_destructor(efl_super(obj, MY_CLASS));
+}
+
+EOLIAN static void
+_efl_ui_datepicker_efl_ui_date_min_set(Eo *obj, Efl_Ui_Datepicker_Data *sd EINA_UNUSED, int year, int month, int day)
+{
+ int new_time[EFL_UI_DATEPICKER_TYPE_COUNT] = {year, month, day};
+
+ if (!_validate_params(year, month, day)) return;
+ if (_date_cmp(sd->min_date, new_time)) return;
+
+ memcpy(sd->min_date, new_time, (sizeof(int) * EFL_UI_DATEPICKER_TYPE_COUNT));
+
+ _validate_date_limits(sd->max_date, sd->min_date, EINA_FALSE);
+ _validate_date_limits(sd->cur_date, sd->min_date, EINA_FALSE);
+
+ DATE_SET(obj);
+ _field_value_update(obj);
+}
+
+EOLIAN static void
+_efl_ui_datepicker_efl_ui_date_min_get(Eo *obj EINA_UNUSED, Efl_Ui_Datepicker_Data *sd, int *year, int *month, int *day)
+{
+ *year = sd->min_date[DATEPICKER_YEAR];
+ *month = sd->min_date[DATEPICKER_MONTH];
+ *day = sd->min_date[DATEPICKER_DAY];
+}
+
+EOLIAN static void
+_efl_ui_datepicker_efl_ui_date_max_set(Eo *obj, Efl_Ui_Datepicker_Data *sd EINA_UNUSED, int year, int month, int day)
+{
+ int new_time[EFL_UI_DATEPICKER_TYPE_COUNT] = {year, month, day};
+
+ if (!_validate_params(year, month, day)) return;
+ if (_date_cmp(sd->max_date, new_time)) return;
+
+ memcpy(sd->max_date, new_time, (sizeof(int) * EFL_UI_DATEPICKER_TYPE_COUNT));
+
+ _validate_date_limits(sd->max_date, sd->min_date, EINA_TRUE);
+ _validate_date_limits(sd->max_date, sd->cur_date, EINA_TRUE);
+
+ DATE_SET(obj);
+ _field_value_update(obj);
+}
+
+EOLIAN static void
+_efl_ui_datepicker_efl_ui_date_max_get(Eo *obj EINA_UNUSED, Efl_Ui_Datepicker_Data *sd, int *year, int *month, int *day)
+{
+ *year = sd->max_date[DATEPICKER_YEAR];
+ *month = sd->max_date[DATEPICKER_MONTH];
+ *day = sd->max_date[DATEPICKER_DAY];
+}
+
+EOLIAN static void
+_efl_ui_datepicker_efl_ui_date_date_set(Eo *obj, Efl_Ui_Datepicker_Data *sd, int year, int month, int day)
+{
+ int new_time[EFL_UI_DATEPICKER_TYPE_COUNT] = {year, month, day};
+
+ if (!_validate_params(year, month, day)) return;
+ if (_date_cmp(sd->cur_date, new_time)) return;
+
+ memcpy(sd->cur_date, new_time, (sizeof(int) * EFL_UI_DATEPICKER_TYPE_COUNT));
+
+ _validate_date_limits(sd->cur_date, sd->min_date, EINA_FALSE);
+ _validate_date_limits(sd->max_date, sd->cur_date, EINA_TRUE);
+
+ DATE_SET(obj);
+ _field_value_update(obj);
+}
+
+EOLIAN static void
+_efl_ui_datepicker_efl_ui_date_date_get(Eo *obj EINA_UNUSED, Efl_Ui_Datepicker_Data *sd, int *year, int *month, int *day)
+{
+ *year = sd->cur_date[DATEPICKER_YEAR];
+ *month = sd->cur_date[DATEPICKER_MONTH];
+ *day = sd->cur_date[DATEPICKER_DAY];
+}
+
+#define EFL_UI_DATEPICKER_EXTRA_OPS \
+ ELM_LAYOUT_SIZING_EVAL_OPS(efl_ui_datepicker), \
+
+#include "efl_ui_datepicker.eo.c"
diff --git a/src/lib/elementary/efl_ui_datepicker.eo b/src/lib/elementary/efl_ui_datepicker.eo
new file mode 100644
index 0000000000..9b372d2bdd
--- /dev/null
+++ b/src/lib/elementary/efl_ui_datepicker.eo
@@ -0,0 +1,21 @@
+class Efl.Ui.Datepicker (Efl.Ui.Layout, Efl.Ui.Datetime, Efl.Ui.Date)
+{
+ [[A Datepicker
+
+ This is a widget which allows the user to pick a date using internal spinner.
+ User can use the internal spinner to select year, month, day or user can enter
+ value using internal entry.
+ ]]
+ methods {
+ }
+ implements {
+ Efl.Object.constructor;
+ Efl.Object.destructor;
+ Efl.Ui.Date.min { get; set; }
+ Efl.Ui.Date.max { get; set; }
+ Efl.Ui.Date.date { get; set; }
+ }
+ events {
+ changed; [[Called when date value changed]]
+ }
+}
diff --git a/src/lib/elementary/efl_ui_datepicker_private.h b/src/lib/elementary/efl_ui_datepicker_private.h
new file mode 100644
index 0000000000..4254ee6b0c
--- /dev/null
+++ b/src/lib/elementary/efl_ui_datepicker_private.h
@@ -0,0 +1,22 @@
+#ifndef EFL_UI_DATEPICKER_PRIVATE_H
+#define EFL_UI_DATEPICKER_PRIVATE_H
+
+#define EFL_UI_DATEPICKER_TYPE_COUNT 3
+
+typedef enum _Efl_Ui_Datepicker_Field_Type
+{
+ DATEPICKER_YEAR,
+ DATEPICKER_MONTH,
+ DATEPICKER_DAY
+} Efl_Ui_Datepicker_Field_Type;
+
+typedef struct _Efl_Ui_Datepicker_Data Efl_Ui_Datepicker_Data;
+struct _Efl_Ui_Datepicker_Data
+{
+ Eo *year, *month, *day;
+ int cur_date[EFL_UI_DATEPICKER_TYPE_COUNT],
+ min_date[EFL_UI_DATEPICKER_TYPE_COUNT],
+ max_date[EFL_UI_DATEPICKER_TYPE_COUNT];
+};
+
+#endif
diff --git a/src/lib/elementary/efl_ui_timepicker.c b/src/lib/elementary/efl_ui_timepicker.c
new file mode 100644
index 0000000000..d8998253a9
--- /dev/null
+++ b/src/lib/elementary/efl_ui_timepicker.c
@@ -0,0 +1,282 @@
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#endif
+
+#include <Elementary.h>
+
+#include "elm_priv.h"
+#include "efl_ui_timepicker_private.h"
+
+#define MY_CLASS EFL_UI_TIMEPICKER_CLASS
+
+#define MY_CLASS_NAME "Efl.Ui.Timepicker"
+
+#define FMT_LEN_MAX 32
+
+#define TIME_GET(obj) \
+ do { \
+ Efl_Time t = efl_ui_datetime_value_get(obj); \
+ sd->cur_time[TIMEPICKER_HOUR] = t.tm_hour; \
+ sd->cur_time[TIMEPICKER_MIN] = t.tm_min; \
+ } while (0)
+
+#define TIME_SET(obj) \
+ do { \
+ Efl_Time t; \
+ t.tm_hour = sd->cur_time[TIMEPICKER_HOUR]; \
+ t.tm_min = sd->cur_time[TIMEPICKER_MIN]; \
+ efl_ui_datetime_value_set(obj, t); \
+ } while (0)
+
+static const char *fmt_char[] = {"IHkl", "M", "Aa"};
+
+static Eina_Bool
+_validate_params(int hour, int min)
+{
+ if (hour < 0 || hour > 23 || min < 0 || min > 59)
+ return EINA_FALSE;
+ else return EINA_TRUE;
+}
+
+static Eina_Bool
+_time_cmp(int time1[], int time2[])
+{
+ unsigned int idx;
+
+ for (idx = 0; idx < EFL_UI_TIMEPICKER_TYPE_COUNT -1; idx++)
+ {
+ if (time1[idx] != time2[idx])
+ return EINA_FALSE;
+ }
+
+ return EINA_TRUE;
+}
+
+static void
+_field_value_update(Eo *obj)
+{
+ Efl_Ui_Timepicker_Data *sd = efl_data_scope_get(obj, MY_CLASS);
+
+ if (!sd->is_24hour)
+ {
+ if (sd->cur_time[TIMEPICKER_HOUR] >= 12)
+ {
+ //TODO: gets text from strftime.
+ efl_text_set(sd->ampm, "PM");
+ efl_ui_range_value_set(sd->hour, sd->cur_time[TIMEPICKER_HOUR] - 12);
+ }
+ else
+ {
+ efl_text_set(sd->ampm, "AM");
+ efl_ui_range_value_set(sd->hour, sd->cur_time[TIMEPICKER_HOUR] + 12);
+ }
+ }
+ efl_ui_range_value_set(sd->min, sd->cur_time[TIMEPICKER_MIN]);
+
+ TIME_SET(obj);
+}
+
+static void
+_field_changed_cb(void *data, const Efl_Event *ev)
+{
+ Efl_Ui_Timepicker_Data *sd = efl_data_scope_get(data, MY_CLASS);
+
+ //TODO: hour value increase when min reached max.
+ if (ev->object == sd->hour)
+ {
+ sd->cur_time[TIMEPICKER_HOUR] = efl_ui_range_value_get(sd->hour);
+ if (!sd->is_24hour && !strcmp(efl_text_get(sd->ampm), "PM"))
+ sd->cur_time[TIMEPICKER_HOUR] += 12;
+ }
+ else if (ev->object == sd->min)
+ sd->cur_time[TIMEPICKER_MIN] = efl_ui_range_value_get(sd->min);
+ else
+ {
+ if (!strcmp(efl_text_get(sd->ampm), "PM"))
+ {
+ efl_text_set(sd->ampm, "AM");
+ sd->cur_time[TIMEPICKER_HOUR] -= 12;
+ }
+ else
+ {
+ efl_text_set(sd->ampm, "PM");
+ sd->cur_time[TIMEPICKER_HOUR] += 12;
+ }
+ }
+
+ TIME_SET(data);
+ efl_event_callback_call(data, EFL_UI_TIMEPICKER_EVENT_CHANGED, NULL);
+}
+
+static void
+_fields_init(Eo *obj)
+{
+ const char *fmt;
+ char ch;
+ int i;
+ int field = 0;
+ char buf[FMT_LEN_MAX];
+
+ Efl_Ui_Timepicker_Data *sd = efl_data_scope_get(obj, MY_CLASS);
+
+ //Field create.
+ sd->hour = efl_add(EFL_UI_SPIN_BUTTON_CLASS, obj,
+ efl_ui_range_min_max_set(efl_added, 1, 12),
+ efl_ui_spin_button_circulate_set(efl_added, EINA_TRUE),
+ efl_ui_spin_button_editable_set(efl_added, EINA_TRUE),
+ efl_event_callback_add(efl_added, EFL_UI_SPIN_EVENT_CHANGED,_field_changed_cb, obj),
+ elm_object_style_set(efl_added, "picker"));
+
+ sd->min = efl_add(EFL_UI_SPIN_BUTTON_CLASS, obj,
+ efl_ui_range_min_max_set(efl_added, 0, 59),
+ efl_ui_spin_button_circulate_set(efl_added, EINA_TRUE),
+ efl_ui_spin_button_editable_set(efl_added, EINA_TRUE),
+ efl_event_callback_add(efl_added, EFL_UI_SPIN_EVENT_CHANGED,_field_changed_cb, obj),
+ elm_object_style_set(efl_added, "picker"));
+
+ sd->ampm = efl_add(EFL_UI_BUTTON_CLASS, obj,
+ efl_event_callback_add(efl_added, EFL_UI_EVENT_CLICKED, _field_changed_cb, obj),
+ elm_object_style_set(efl_added, "ampm"));
+
+ TIME_GET(obj);
+
+ sd->is_24hour = EINA_FALSE;
+
+ _field_value_update(obj);
+
+ fmt = efl_ui_datetime_format_get(obj);
+ if (!fmt)
+ {
+ ERR("Failed to get current format.");
+ //Gives default format when the gets format failed.
+ fmt = "%H:%M %a";
+ }
+
+ //Sort fields by format.
+ while((ch = *fmt))
+ {
+ //TODO: ignore extensions and separators.
+ for (i = 0; i < EFL_UI_TIMEPICKER_TYPE_COUNT; i++)
+ {
+ if (strchr(fmt_char[i], ch))
+ {
+ snprintf(buf, sizeof(buf), "field%d", field);
+ if (i == TIMEPICKER_HOUR)
+ efl_content_set(efl_part(obj, buf), sd->hour);
+ else if (i == TIMEPICKER_MIN)
+ efl_content_set(efl_part(obj, buf), sd->min);
+ else
+ {
+ //TODO: monitoring locale change and update field location.
+ if (field == 0)
+ {
+ elm_object_signal_emit(obj, "elm,state,colon,visible,field1", "elm");
+ elm_object_signal_emit(obj, "elm,state,colon,invisible,field0", "elm");
+ }
+ else
+ {
+ elm_object_signal_emit(obj, "elm,state,colon,visible,field0", "elm");
+ elm_object_signal_emit(obj, "elm,state,colon,invisible,field1", "elm");
+ }
+
+ elm_layout_signal_emit(obj, "elm,state,ampm,visible", "elm");
+ edje_object_message_signal_process(elm_layout_edje_get(obj));
+ efl_content_set(efl_part(obj, buf), sd->ampm);
+ }
+
+ field++;
+ break;
+ }
+ }
+ fmt++;
+ }
+}
+
+EOLIAN static void
+_efl_ui_timepicker_elm_layout_sizing_eval(Eo *obj, Efl_Ui_Timepicker_Data *_pd EINA_UNUSED)
+{
+ Evas_Coord minw = -1, minh = -1;
+ ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
+
+ elm_coords_finger_size_adjust(1, &minw, 1, &minh);
+ edje_object_size_min_restricted_calc
+ (wd->resize_obj, &minw, &minh, minw, minh);
+ elm_coords_finger_size_adjust(1, &minw, 1, &minh);
+ evas_object_size_hint_min_set(obj, minw, minh);
+ evas_object_size_hint_max_set(obj, -1, -1);
+}
+
+EOLIAN static Eo *
+_efl_ui_timepicker_efl_object_constructor(Eo *obj, Efl_Ui_Timepicker_Data *sd EINA_UNUSED)
+{
+ ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, NULL);
+
+ if (!elm_widget_theme_klass_get(obj))
+ elm_widget_theme_klass_set(obj, "timepicker");
+ obj = efl_constructor(efl_super(obj, MY_CLASS));
+
+ if (!elm_widget_theme_object_set(obj, wd->resize_obj,
+ elm_widget_theme_klass_get(obj),
+ elm_widget_theme_element_get(obj),
+ elm_widget_theme_style_get(obj)))
+ CRI("Failed to set layout!");
+
+ _fields_init(obj);
+
+ elm_widget_sub_object_parent_add(obj);
+
+ elm_widget_can_focus_set(obj, EINA_TRUE);
+
+ return obj;
+}
+
+EOLIAN static void
+_efl_ui_timepicker_efl_object_destructor(Eo *obj, Efl_Ui_Timepicker_Data *sd EINA_UNUSED)
+{
+ efl_destructor(efl_super(obj, MY_CLASS));
+}
+
+EOLIAN static void
+_efl_ui_timepicker_efl_ui_time_time_set(Eo *obj, Efl_Ui_Timepicker_Data *sd, int hour, int min)
+{
+ int new_time[EFL_UI_TIMEPICKER_TYPE_COUNT - 1] = {hour, min};
+
+ if (!_validate_params(hour, min)) return;
+ if (_time_cmp(sd->cur_time, new_time)) return;
+
+ memcpy(sd->cur_time, new_time, (sizeof(int) * (EFL_UI_TIMEPICKER_TYPE_COUNT -1)));
+
+ TIME_SET(obj);
+ _field_value_update(obj);
+}
+
+EOLIAN static void
+_efl_ui_timepicker_efl_ui_time_time_get(Eo *obj EINA_UNUSED, Efl_Ui_Timepicker_Data *sd, int *hour, int *min)
+{
+ *hour = sd->cur_time[TIMEPICKER_HOUR];
+ *min = sd->cur_time[TIMEPICKER_MIN];
+}
+
+EOLIAN static void
+_efl_ui_timepicker_ampm_set(Eo *obj, Efl_Ui_Timepicker_Data *sd, Eina_Bool is_24hour)
+{
+ if (sd->is_24hour == is_24hour) return;
+
+ sd->is_24hour = is_24hour;
+ if (sd->is_24hour == EINA_TRUE)
+ elm_layout_signal_emit(obj, "elm,state,ampm,invisible", "elm");
+ else
+ elm_layout_signal_emit(obj, "elm,state,ampm,visible", "elm");
+ _field_value_update(obj);
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_timepicker_ampm_get(Eo *obj EINA_UNUSED, Efl_Ui_Timepicker_Data *sd)
+{
+ return sd->is_24hour;
+}
+
+#define EFL_UI_TIMEPICKER_EXTRA_OPS \
+ ELM_LAYOUT_SIZING_EVAL_OPS(efl_ui_timepicker), \
+
+#include "efl_ui_timepicker.eo.c"
diff --git a/src/lib/elementary/efl_ui_timepicker.eo b/src/lib/elementary/efl_ui_timepicker.eo
new file mode 100644
index 0000000000..ea2577867e
--- /dev/null
+++ b/src/lib/elementary/efl_ui_timepicker.eo
@@ -0,0 +1,26 @@
+class Efl.Ui.Timepicker (Efl.Ui.Layout, Efl.Ui.Datetime, Efl.Ui.Time)
+{
+ [[A timepicker
+
+ This is a widget which allows the user to pick a time using internal spinner.
+ User can use the internal spinner to select hour, minute, AM/PM or user can enter
+ value using internal entry.
+ ]]
+ methods {
+ @property ampm {
+ [[Control the picker will displayed for 24 hour or 12 hour including the AM/PM buttons.]]
+ set {} get {}
+ values {
+ is_24hour: bool; [[$ture the 24 hour timepicker will be shown, $false 12 hour timepicker will be shown.]]
+ }
+ }
+ }
+ implements {
+ Efl.Object.constructor;
+ Efl.Object.destructor;
+ Efl.Ui.Time.time { get; set; }
+ }
+ events {
+ changed; [[Called when date changed]]
+ }
+}
diff --git a/src/lib/elementary/efl_ui_timepicker_private.h b/src/lib/elementary/efl_ui_timepicker_private.h
new file mode 100644
index 0000000000..e2ace95f68
--- /dev/null
+++ b/src/lib/elementary/efl_ui_timepicker_private.h
@@ -0,0 +1,21 @@
+#ifndef EFL_UI_TIMEPICKER_PRIVATE_H
+#define EFL_UI_TIMEPICKER_PRIVATE_H
+
+#define EFL_UI_TIMEPICKER_TYPE_COUNT 3
+
+typedef enum _Efl_Ui_Timepicker_Field_Type
+{
+ TIMEPICKER_HOUR,
+ TIMEPICKER_MIN,
+ TIMEPICKER_AMPM
+} Efl_Ui_Timepicker_Field_Type;
+
+typedef struct _Efl_Ui_Timepicker_Data Efl_Ui_Timepicker_Data;
+struct _Efl_Ui_Timepicker_Data
+{
+ Eo *hour, *min, *ampm;
+ int cur_time[EFL_UI_TIMEPICKER_TYPE_COUNT];
+ Eina_Bool is_24hour;
+};
+
+#endif