diff --git a/config/default/base.src.in b/config/default/base.src.in index dfecc901d8..9128b98d97 100644 --- a/config/default/base.src.in +++ b/config/default/base.src.in @@ -727,6 +727,24 @@ group "Elm_Config" struct { value "action" string: "move"; value "params" string: "down"; } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "Return"; + value "action" string: "activate"; + value "params" string: ""; + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "KP_Enter"; + value "action" string: "activate"; + value "params" string: ""; + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "space"; + value "action" string: "activate"; + value "params" string: ""; + } } } group "Elm_Config_Bindings_Widget" struct { diff --git a/config/mobile/base.src.in b/config/mobile/base.src.in index ebc5070ae6..f1a357b22e 100644 --- a/config/mobile/base.src.in +++ b/config/mobile/base.src.in @@ -731,6 +731,24 @@ group "Elm_Config" struct { value "action" string: "move"; value "params" string: "down"; } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "Return"; + value "action" string: "activate"; + value "params" string: ""; + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "KP_Enter"; + value "action" string: "activate"; + value "params" string: ""; + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "space"; + value "action" string: "activate"; + value "params" string: ""; + } } } group "Elm_Config_Bindings_Widget" struct { diff --git a/config/standard/base.src.in b/config/standard/base.src.in index d5cd732f3f..678e274515 100644 --- a/config/standard/base.src.in +++ b/config/standard/base.src.in @@ -728,6 +728,24 @@ group "Elm_Config" struct { value "action" string: "move"; value "params" string: "down"; } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "Return"; + value "action" string: "activate"; + value "params" string: ""; + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "KP_Enter"; + value "action" string: "activate"; + value "params" string: ""; + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "space"; + value "action" string: "activate"; + value "params" string: ""; + } } } group "Elm_Config_Bindings_Widget" struct { diff --git a/data/elementary/themes/edc/elm/calendar.edc b/data/elementary/themes/edc/elm/calendar.edc index 662bd51def..8dfffc169c 100644 --- a/data/elementary/themes/edc/elm/calendar.edc +++ b/data/elementary/themes/edc/elm/calendar.edc @@ -200,6 +200,21 @@ visible: 1; \ } \ } \ + part { name: "cit_"#_pos".glow"; mouse_events: 0; \ + description { state: "default" 0.0; \ + rel1.to: "cit_"#_pos".rect"; \ + rel2.to: "cit_"#_pos".rect"; \ + image.normal: "box_glow.png"; \ + image.border: 12 12 12 12; \ + image.middle: 0; \ + fill.smooth: 0; \ + visible: 0; \ + } \ + description { state: "focused" 0.0; \ + inherit: "default" 0.0; \ + visible: 1; \ + } \ + } \ part { name: "cit_"#_pos".text"; type: TEXTBLOCK; mouse_events: 0; \ scale: 1; \ description { state: "default" 0.0; \ @@ -279,6 +294,26 @@ target: "cit_"#_pos".pat"; \ target: "cit_"#_pos".selected"; \ } \ + program { \ + name: "cit_"#_pos".focus_highlighted"; \ + signal: "cit_"#_pos",focused"; \ + source: "elm"; \ + script { \ + set_int(item_focus_enabled, 1); \ + set_int(last_focused_item, _pos); \ + if (get_int(win_focus_enabled) == 1) \ + set_state(PART:"cit_"#_pos".glow", "focused", 0.0); \ + } \ + } \ + program { \ + name: "cit_"#_pos".focus_unhighlighed"; \ + signal: "cit_"#_pos",unfocused"; \ + source: "elm"; \ + script { \ + set_int(item_focus_enabled, 0); \ + set_state(PART:"cit_"#_pos".glow", "default", 0.0); \ + } \ + } \ program { \ name: "cit_"#_pos".is_today"; \ signal: "cit_"#_pos",today"; \ @@ -413,9 +448,14 @@ group { name: "elm/calendar/base/default"; images.image: "sym_right_glow_normal.png" COMP; images.image: "icon_border_remember.png" COMP; images.image: "outline_glow.png" COMP; + images.image: "box_glow.png" COMP; images.image: "diagonal_stripes.png" COMP; + data.item: "focus_highlight" "on"; script { public rtl; + public win_focus_enabled; + public item_focus_enabled; + public last_focused_item; } styles { CIT_STYLES @@ -493,6 +533,28 @@ group { name: "elm/calendar/base/default"; CIT(21) CIT(22) CIT(23) CIT(24) CIT(25) CIT(26) CIT(27) CIT(28) CIT(29) CIT(30) CIT(31) CIT(32) CIT(33) CIT(34) CIT(35) CIT(36) CIT(37) CIT(38) CIT(39) CIT(40) CIT(41) + + } + programs { + program { + signal: "elm,action,focus_highlight,show"; + source: "elm"; + script { + set_int(win_focus_enabled, 1); + if (get_int(item_focus_enabled) == 1) { + new value[32]; + snprintf(value, 32, "cit_%d,focused", get_int(last_focused_item)); + emit(value, "elm"); + } + } + } + program { + signal: "elm,action,focus_highlight,hide"; + source: "elm"; + script { + set_int(win_focus_enabled, 0); + } + } } } diff --git a/src/lib/elementary/elm_calendar.c b/src/lib/elementary/elm_calendar.c index b0fcc580b7..6e57c26346 100644 --- a/src/lib/elementary/elm_calendar.c +++ b/src/lib/elementary/elm_calendar.c @@ -125,9 +125,11 @@ _eina_tmpstr_steal(Eina_Tmpstr *s) #endif static Eina_Bool _key_action_move(Evas_Object *obj, const char *params); +static Eina_Bool _key_action_activate(Evas_Object *obj, const char *params); static const Elm_Action key_actions[] = { {"move", _key_action_move}, + {"activate", _key_action_activate}, {NULL, NULL} }; @@ -218,7 +220,7 @@ _select(Evas_Object *obj, ELM_CALENDAR_DATA_GET(obj, sd); - sd->selected_it = selected; + sd->focused_it = sd->selected_it = selected; snprintf(emission, sizeof(emission), "cit_%i,selected", selected); elm_layout_signal_emit(obj, emission, "elm"); } @@ -1275,6 +1277,47 @@ _get_item_day(Evas_Object *obj, return day; } +static void +_update_unfocused_it(Evas_Object *obj, int unfocused_it) +{ + int day; + char emission[32]; + + ELM_CALENDAR_DATA_GET(obj, sd); + + day = _get_item_day(obj, unfocused_it); + if (!day) + return; + + sd->focused_it = -1; + + snprintf(emission, sizeof(emission), "cit_%i,unfocused", unfocused_it); + elm_layout_signal_emit(obj, emission, "elm"); +} + +static Eina_Bool +_update_focused_it(Evas_Object *obj, int focused_it) +{ + int day; + char emission[32]; + + ELM_CALENDAR_DATA_GET(obj, sd); + + day = _get_item_day(obj, focused_it); + if (!day) + return EINA_FALSE; + + snprintf(emission, sizeof(emission), "cit_%i,unfocused", sd->focused_it); + elm_layout_signal_emit(obj, emission, "elm"); + + sd->focused_it = focused_it; + + snprintf(emission, sizeof(emission), "cit_%i,focused", sd->focused_it); + elm_layout_signal_emit(obj, emission, "elm"); + + return EINA_TRUE; +} + static void _update_sel_it(Evas_Object *obj, int sel_it) @@ -1293,6 +1336,8 @@ _update_sel_it(Evas_Object *obj, _unselect(obj, sd->selected_it); if (!sd->selected) sd->selected = EINA_TRUE; + if (sd->focused_it) + _update_unfocused_it(obj, sd->focused_it); sd->selected_time.tm_mday = day; _fix_selected_time(sd); @@ -1348,11 +1393,24 @@ _update_cur_date(void *data) return ECORE_CALLBACK_RENEW; } +static Eina_Bool +_key_action_activate(Evas_Object *obj, const char *params EINA_UNUSED) +{ + ELM_CALENDAR_DATA_GET(obj, sd); + + _update_sel_it(obj, sd->focused_it); + + return EINA_TRUE; +} + static Eina_Bool _key_action_move(Evas_Object *obj, const char *params) { ELM_CALENDAR_DATA_GET(obj, sd); const char *dir = params; + Eina_Bool ret, double_spinner = EINA_FALSE; + + ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd); _elm_widget_focus_auto_show(obj); if (!strcmp(dir, "prior")) @@ -1367,33 +1425,212 @@ _key_action_move(Evas_Object *obj, const char *params) && ((sd->select_mode != ELM_CALENDAR_SELECT_MODE_ONDEMAND) || (sd->selected))) { + if (edje_object_part_exists(wd->resize_obj, ELM_CALENDAR_BUTTON_YEAR_RIGHT)) + double_spinner = EINA_TRUE; + if (!strcmp(dir, "left")) { if ((sd->select_mode != ELM_CALENDAR_SELECT_MODE_ONDEMAND) || ((sd->shown_time.tm_year == sd->selected_time.tm_year) && (sd->shown_time.tm_mon == sd->selected_time.tm_mon))) - _update_sel_it(obj, sd->selected_it - 1); + { + //Double spinner case. + if (double_spinner) + { + if (elm_object_focus_get(sd->inc_btn_year)) + { + elm_object_focus_set(sd->dec_btn_year, EINA_TRUE); + return EINA_TRUE; + } + else if (elm_object_focus_get(sd->dec_btn_year)) + { + elm_object_focus_set(sd->inc_btn_month, EINA_TRUE); + return EINA_TRUE; + } + } + + //Give focus to dec_btn_month when left key down on the inc_btn_month. + //Leave focus, if key down on dec_btn_month. + if (elm_object_focus_get(sd->inc_btn_month)) + { + elm_object_focus_set(sd->dec_btn_month, EINA_TRUE); + return EINA_TRUE; + } + else if (elm_object_focus_get(sd->dec_btn_month)) return EINA_FALSE; + + //If key move from the left edge of the calendar, + //Leave the focus policy on window. + if (sd->focused_it % ELM_DAY_LAST == 0) + return EINA_FALSE; + + //Focus on the day before the day. + ret = _update_focused_it(obj, sd->focused_it - 1); + if (!ret) return EINA_FALSE; + } } else if (!strcmp(dir, "right")) { if ((sd->select_mode != ELM_CALENDAR_SELECT_MODE_ONDEMAND) || ((sd->shown_time.tm_year == sd->selected_time.tm_year) && (sd->shown_time.tm_mon == sd->selected_time.tm_mon))) - _update_sel_it(obj, sd->selected_it + 1); + { + //Double spinner case. + if (double_spinner) + { + if (elm_object_focus_get(sd->inc_btn_year)) return EINA_FALSE; + else if (elm_object_focus_get(sd->dec_btn_year)) + { + elm_object_focus_set(sd->inc_btn_year, EINA_TRUE); + return EINA_TRUE; + } + else if (elm_object_focus_get(sd->inc_btn_month)) + { + elm_object_focus_set(sd->dec_btn_year, EINA_TRUE); + return EINA_TRUE; + } + } + + //Give focus to inc_btn_month when right key down on the dec_btn_month. + if (elm_object_focus_get(sd->dec_btn_month)) + { + elm_object_focus_set(sd->inc_btn_month, EINA_TRUE); + return EINA_TRUE; + } + else if (elm_object_focus_get(sd->inc_btn_month)) return EINA_FALSE; + + //If key move from the right edge of the calendar, + //Leave the focus policy on window. + if (sd->focused_it % ELM_DAY_LAST == ELM_DAY_LAST - 1) + return EINA_FALSE; + + //Focus on the day after the day. + ret = _update_focused_it(obj, sd->focused_it + 1); + if (!ret) return EINA_FALSE; + } } else if (!strcmp(dir, "up")) { if ((sd->select_mode != ELM_CALENDAR_SELECT_MODE_ONDEMAND) || ((sd->shown_time.tm_year == sd->selected_time.tm_year) && (sd->shown_time.tm_mon == sd->selected_time.tm_mon))) - _update_sel_it(obj, sd->selected_it - ELM_DAY_LAST); + { + //double spinner case. + if (double_spinner) + { + if (elm_object_focus_get(sd->inc_btn_year)) + { + elm_object_focus_set(sd->inc_btn_year, EINA_FALSE); + return EINA_FALSE; + } + else if (elm_object_focus_get(sd->dec_btn_year)) + { + elm_object_focus_set(sd->dec_btn_year, EINA_FALSE); + return EINA_FALSE; + } + } + + //If the dec_btn_month, or inc_btn_month has focus. + //Focus unset and leave the focus policy on window. + if (elm_object_focus_get(sd->dec_btn_month)) + { + elm_object_focus_set(sd->dec_btn_month, EINA_FALSE); + return EINA_FALSE; + } + else if (elm_object_focus_get(sd->inc_btn_month)) + { + elm_object_focus_set(sd->inc_btn_month, EINA_FALSE); + return EINA_FALSE; + } + + //If the focus item is the first week of month. + if ((sd->focused_it >= 0) && (sd->focused_it < ELM_DAY_LAST)) + { + //Give focus to inc_btn_month(right side located button) + //If the focused item is smaller than 4. + //Otherwise, give focus to dec_btn_month. + if (sd->focused_it > (ELM_DAY_LAST / 2)) + //Double spinner case. + if (edje_object_part_exists(wd->resize_obj, ELM_CALENDAR_BUTTON_YEAR_RIGHT)) + elm_object_focus_set(sd->inc_btn_year, EINA_TRUE); + else + elm_object_focus_set(sd->inc_btn_month, EINA_TRUE); + else + elm_object_focus_set(sd->dec_btn_month, EINA_TRUE); + + _update_unfocused_it(obj, sd->focused_it); + return EINA_TRUE; + } + + //Focus on the last week day. + ret = _update_focused_it(obj, sd->focused_it - ELM_DAY_LAST); + if (!ret) + { + //If focused day is not available(not belongs to current month) + //Take a focus from item and give the focus to suitable button. + if (sd->focused_it >= ELM_DAY_LAST && sd->focused_it < (ELM_DAY_LAST * 2)) + { + if (sd->focused_it > (ELM_DAY_LAST + (ELM_DAY_LAST / 2))) + //Double spinner case. + if (edje_object_part_exists(wd->resize_obj, ELM_CALENDAR_BUTTON_YEAR_RIGHT)) + elm_object_focus_set(sd->inc_btn_year, EINA_TRUE); + else + elm_object_focus_set(sd->inc_btn_month, EINA_TRUE); + else + elm_object_focus_set(sd->dec_btn_month, EINA_TRUE); + + _update_unfocused_it(obj, sd->focused_it); + return EINA_TRUE; + } + } + } } else if (!strcmp(dir, "down")) { if ((sd->select_mode != ELM_CALENDAR_SELECT_MODE_ONDEMAND) || ((sd->shown_time.tm_year == sd->selected_time.tm_year) && (sd->shown_time.tm_mon == sd->selected_time.tm_mon))) - _update_sel_it(obj, sd->selected_it + ELM_DAY_LAST); + { + //double spinner case. + if (double_spinner) + { + if (elm_object_focus_get(sd->inc_btn_year)) + { + elm_object_focus_set(sd->inc_btn_year, EINA_FALSE); + evas_object_focus_set(obj, EINA_TRUE); + _update_focused_it(obj, (ELM_DAY_LAST - 1)); + return EINA_TRUE; + } + else if (elm_object_focus_get(sd->dec_btn_year)) + { + elm_object_focus_set(sd->dec_btn_year, EINA_FALSE); + evas_object_focus_set(obj, EINA_TRUE); + _update_focused_it(obj, sd->first_day_it); + return EINA_TRUE; + } + } + + //If the XXX_btn_month has focus. + //Set as false to button focus and give to focus to first item of the calendar. + //Otherwise, Give the focus to last day of first week of calendar. + if (elm_object_focus_get(sd->dec_btn_month)) + { + elm_object_focus_set(sd->dec_btn_month, EINA_FALSE); + evas_object_focus_set(obj, EINA_TRUE); + _update_focused_it(obj, sd->first_day_it); + return EINA_TRUE; + } + else if(elm_object_focus_get(sd->inc_btn_month)) + { + elm_object_focus_set(sd->inc_btn_month, EINA_FALSE); + evas_object_focus_set(obj, EINA_TRUE); + _update_focused_it(obj, (ELM_DAY_LAST - 1)); + return EINA_TRUE; + } + + //Focus on the next week day. + ret = _update_focused_it(obj, sd->focused_it + ELM_DAY_LAST); + if (!ret) return EINA_FALSE; + } } else return EINA_FALSE; } @@ -1402,6 +1639,22 @@ _key_action_move(Evas_Object *obj, const char *params) return EINA_TRUE; } +EOLIAN static Eina_Bool +_elm_calendar_elm_widget_on_focus(Eo *obj, Elm_Calendar_Data *sd, Elm_Object_Item *item EINA_UNUSED) +{ + Eina_Bool int_ret = EINA_FALSE; + + int_ret = elm_obj_widget_on_focus(efl_super(obj, MY_CLASS), NULL); + if (!int_ret) return EINA_FALSE; + + if (elm_widget_focus_get(obj)) + sd->focused_it = sd->selected_it; + else + _update_unfocused_it(obj, sd->focused_it); + + return EINA_TRUE; +} + EOLIAN static Eina_Bool _elm_calendar_elm_widget_event(Eo *obj, Elm_Calendar_Data *sd EINA_UNUSED, Evas_Object *src, Evas_Callback_Type type, void *event_info) { @@ -1545,7 +1798,7 @@ static Eina_Bool _elm_calendar_smart_focus_next_enable = EINA_FALSE; EOLIAN static Eina_Bool _elm_calendar_elm_widget_focus_next_manager_is(Eo *obj EINA_UNUSED, Elm_Calendar_Data *_pd EINA_UNUSED) { - return EINA_TRUE; + return EINA_FALSE; } EOLIAN static Eina_Bool @@ -2080,6 +2333,7 @@ _elm_calendar_elm_interface_atspi_widget_action_elm_actions_get(Eo *obj EINA_UNU { "move,right", "move", "right", _key_action_move}, { "move,up", "move", "up", _key_action_move}, { "move,down", "move", "down", _key_action_move}, + { "activate", "activate", NULL, _key_action_activate}, { NULL, NULL, NULL, NULL } }; return &atspi_actions[0]; diff --git a/src/lib/elementary/elm_calendar.eo b/src/lib/elementary/elm_calendar.eo index b312f486be..9890b2f1c9 100644 --- a/src/lib/elementary/elm_calendar.eo +++ b/src/lib/elementary/elm_calendar.eo @@ -419,6 +419,7 @@ class Elm.Calendar (Elm.Layout, Elm.Interface.Atspi_Widget_Action) Elm.Widget.focus_direction_manager_is; Elm.Widget.access; Elm.Widget.focus_next; + Elm.Widget.on_focus; Elm.Widget.event; Elm.Layout.sizing_eval; Elm.Interface.Atspi_Widget_Action.elm_actions.get; diff --git a/src/lib/elementary/elm_widget_calendar.h b/src/lib/elementary/elm_widget_calendar.h index 18d3cf7546..b8f7bdf78f 100644 --- a/src/lib/elementary/elm_widget_calendar.h +++ b/src/lib/elementary/elm_widget_calendar.h @@ -38,7 +38,7 @@ struct _Elm_Calendar_Data Eina_List *marks; double interval, first_interval; int spin_speed; - int today_it, selected_it, first_day_it; + int today_it, selected_it, first_day_it, focused_it; Ecore_Timer *spin_month, *spin_year, *update_timer; Elm_Calendar_Format_Cb format_func; const char *weekdays[ELM_DAY_LAST];