diff options
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 |