diff --git a/src/Makefile_Elementary.am b/src/Makefile_Elementary.am index f763e60225..e371e4f5af 100644 --- a/src/Makefile_Elementary.am +++ b/src/Makefile_Elementary.am @@ -154,6 +154,7 @@ elm_private_eolian_files = \ tests/elementary/focus_test.eo \ tests/elementary/focus_test_sub_main.eo \ lib/elementary/efl_ui_focus_rectangle.eo \ + lib/elementary/elm_calendar_item.eo \ $(NULL) # Legacy classes - not part of public EO API diff --git a/src/lib/elementary/elm_calendar.c b/src/lib/elementary/elm_calendar.c index 54c642d1ac..a525c6e42d 100644 --- a/src/lib/elementary/elm_calendar.c +++ b/src/lib/elementary/elm_calendar.c @@ -4,10 +4,13 @@ #define ELM_INTERFACE_ATSPI_ACCESSIBLE_PROTECTED #define ELM_INTERFACE_ATSPI_WIDGET_ACTION_PROTECTED +#define EFL_UI_FOCUS_COMPOSITION_PROTECTED #include #include "elm_priv.h" #include "elm_widget_calendar.h" +#include "efl_ui_focus_composition.eo.h" +#include "elm_calendar_item.eo.h" #define MY_CLASS ELM_CALENDAR_CLASS @@ -124,11 +127,9 @@ _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} }; @@ -479,6 +480,30 @@ _access_calendar_register(Evas_Object *obj) _access_calendar_item_register(obj); } +static void +_flush_calendar_composite_elements(Evas_Object *obj, Elm_Calendar_Data *sd) +{ + Eina_List *items = NULL; + int max_day = _maxdays_get(&sd->shown_time, 0); + +#define EXTEND(v) \ + if (v) items = eina_list_append(items, v); \ + + EXTEND(sd->month_access); + EXTEND(sd->dec_btn_month); + EXTEND(sd->inc_btn_month); + EXTEND(sd->year_access); + EXTEND(sd->dec_btn_year); + EXTEND(sd->inc_btn_year); + +#undef EXTEND + + for (int i = sd->first_day_it; i <= max_day; ++i) + items = eina_list_append(items, sd->items[i]); + + efl_ui_focus_composition_elements_set(obj, items); +} + static void _populate(Evas_Object *obj) { @@ -702,6 +727,8 @@ _populate(Evas_Object *obj) elm_layout_thaw(obj); edje_object_message_signal_process(elm_layout_edje_get(obj)); + + _flush_calendar_composite_elements(obj, sd); } static void @@ -1403,242 +1430,6 @@ _key_action_activate(Evas_Object *obj, const char *params EINA_UNUSED) 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, EINA_FALSE); - - _elm_widget_focus_auto_show(obj); - if (!strcmp(dir, "prior")) - { - if (_update_data(obj, EINA_TRUE, -1)) _populate(obj); - } - else if (!strcmp(dir, "next")) - { - if (_update_data(obj, EINA_TRUE, 1)) _populate(obj); - } - else if ((sd->select_mode != ELM_CALENDAR_SELECT_MODE_NONE) - && ((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))) - { - //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))) - { - //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))) - { - //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 (double_spinner) - 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 (double_spinner) - 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))) - { - //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; - } - else return EINA_FALSE; - - return EINA_TRUE; -} - EOLIAN static Eina_Bool _elm_calendar_elm_widget_on_focus_update(Eo *obj, Elm_Calendar_Data *sd, Elm_Object_Item *item EINA_UNUSED) { @@ -1751,6 +1542,12 @@ _elm_calendar_efl_canvas_group_group_add(Eo *obj, Elm_Calendar_Data *priv) // ACCESS if ((_elm_config->access_mode != ELM_ACCESS_MODE_OFF)) _access_calendar_spinner_register(obj); + + // Items for composition + for (int i = 0; i < 42; ++i) + { + priv->items[i] = efl_add(ELM_CALENDAR_ITEM_CLASS, obj, elm_calendar_item_day_number_set(efl_added, i)); + } } EOLIAN static void @@ -1779,55 +1576,6 @@ _elm_calendar_efl_canvas_group_group_del(Eo *obj, Elm_Calendar_Data *sd) 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_FALSE; -} - -EOLIAN static Eina_Bool -_elm_calendar_elm_widget_focus_direction_manager_is(Eo *obj EINA_UNUSED, Elm_Calendar_Data *_pd EINA_UNUSED) -{ - return EINA_FALSE; -} - -EOLIAN static Eina_Bool -_elm_calendar_elm_widget_focus_next(Eo *obj, Elm_Calendar_Data *sd, Elm_Focus_Direction dir, Evas_Object **next, Elm_Object_Item **next_item) -{ - int maxdays, day, i; - Eina_List *items = NULL; - Evas_Object *ao; - Evas_Object *po; - - items = eina_list_append(items, sd->month_access); - items = eina_list_append(items, sd->dec_btn_month); - items = eina_list_append(items, sd->inc_btn_month); - - items = eina_list_append(items, sd->year_access); - items = eina_list_append(items, sd->dec_btn_year); - items = eina_list_append(items, sd->inc_btn_year); - - day = 0; - maxdays = _maxdays_get(&sd->shown_time, 0); - for (i = 0; i < 42; i++) - { - if ((!day) && (i == sd->first_day_it)) day = 1; - if ((day) && (day <= maxdays)) - { - char pname[14]; - snprintf(pname, sizeof(pname), "cit_%i.access", i); - - po = (Evas_Object *)edje_object_part_object_get - (elm_layout_edje_get(obj), pname); - ao = evas_object_data_get(po, "_part_access_obj"); - items = eina_list_append(items, ao); - } - } - - return elm_widget_focus_list_next_get - (obj, items, eina_list_data_get, dir, next, next_item); -} - static void _access_obj_process(Evas_Object *obj, Eina_Bool is_access) { @@ -2310,12 +2058,6 @@ EOLIAN static const Elm_Atspi_Action* _elm_calendar_elm_interface_atspi_widget_action_elm_actions_get(Eo *obj EINA_UNUSED, Elm_Calendar_Data *sd EINA_UNUSED) { static Elm_Atspi_Action atspi_actions[] = { - { "move,prior", "move", "prior", _key_action_move}, - { "move,next", "move", "next", _key_action_move}, - { "move,left", "move", "left", _key_action_move}, - { "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 } }; @@ -2333,3 +2075,51 @@ ELM_WIDGET_KEY_DOWN_DEFAULT_IMPLEMENT(elm_calendar, Elm_Calendar_Data) EFL_CANVAS_GROUP_ADD_DEL_OPS(elm_calendar) #include "elm_calendar.eo.c" + +typedef struct { + int v; + Evas_Object *part; +} Elm_Calendar_Item_Data; + +EOLIAN static void +_elm_calendar_item_day_number_set(Eo *obj, Elm_Calendar_Item_Data *pd, int i) +{ + char pname[14]; + Evas_Object *po; + + pd->v = i; + snprintf(pname, sizeof(pname), "cit_%i.access", i); + + po = (Evas_Object *)edje_object_part_object_get + (elm_layout_edje_get(efl_parent_get(obj)), pname); + + if (_elm_config->access_mode != ELM_ACCESS_MODE_ON) + pd->part = po; + else + pd->part = evas_object_data_get(po, "_part_access_obj"); + + EINA_SAFETY_ON_NULL_RETURN(pd->part); +} + +EOLIAN static int +_elm_calendar_item_day_number_get(Eo *obj EINA_UNUSED, Elm_Calendar_Item_Data *pd) +{ + return pd->v; +} + +EOLIAN static void +_elm_calendar_item_efl_ui_focus_object_focus_set(Eo *obj, Elm_Calendar_Item_Data *pd, Eina_Bool focus) +{ + efl_ui_focus_object_focus_set(efl_super(obj, ELM_CALENDAR_ITEM_CLASS), focus); + + _update_focused_it(efl_parent_get(obj), pd->v); + evas_object_focus_set(pd->part, efl_ui_focus_object_focus_get(obj)); +} + +EOLIAN static Eina_Rect +_elm_calendar_item_efl_ui_focus_object_focus_geometry_get(Eo *obj EINA_UNUSED, Elm_Calendar_Item_Data *pd) +{ + return efl_gfx_geometry_get(pd->part); +} + +#include "elm_calendar_item.eo.c" diff --git a/src/lib/elementary/elm_calendar.eo b/src/lib/elementary/elm_calendar.eo index eaa05d214f..556d78ab3d 100644 --- a/src/lib/elementary/elm_calendar.eo +++ b/src/lib/elementary/elm_calendar.eo @@ -72,7 +72,7 @@ struct Elm.Calendar.Mark; [[Item handle for a calendar mark. with @Elm.Calendar.mark_del. ]] -class Elm.Calendar (Efl.Ui.Layout, Elm.Interface.Atspi_Widget_Action) +class Elm.Calendar (Efl.Ui.Layout, Efl.Ui.Focus.Composition, Elm.Interface.Atspi_Widget_Action) { [[Calendar widget @@ -413,10 +413,7 @@ class Elm.Calendar (Efl.Ui.Layout, Elm.Interface.Atspi_Widget_Action) Efl.Object.constructor; Efl.Canvas.Group.group_calculate; Elm.Widget.theme_apply; - Elm.Widget.focus_next_manager_is; - Elm.Widget.focus_direction_manager_is; Elm.Widget.on_access_update; - Elm.Widget.focus_next; Elm.Widget.on_focus_update; Elm.Widget.widget_event; Elm.Interface.Atspi_Widget_Action.elm_actions { get; } diff --git a/src/lib/elementary/elm_calendar_item.eo b/src/lib/elementary/elm_calendar_item.eo new file mode 100644 index 0000000000..7aa9495b2b --- /dev/null +++ b/src/lib/elementary/elm_calendar_item.eo @@ -0,0 +1,14 @@ +class Elm.Calendar.Item (Efl.Object, Efl.Ui.Focus.Object) +{ + methods { + @property day_number { + values { + i : int; + } + } + } + implements { + Efl.Ui.Focus.Object.focus {set;} + Efl.Ui.Focus.Object.focus_geometry {get;} + } +} diff --git a/src/lib/elementary/elm_widget_calendar.h b/src/lib/elementary/elm_widget_calendar.h index a9ca2f485c..e68c490f9d 100644 --- a/src/lib/elementary/elm_widget_calendar.h +++ b/src/lib/elementary/elm_widget_calendar.h @@ -50,6 +50,7 @@ struct _Elm_Calendar_Data Evas_Object *inc_btn_year; Evas_Object *dec_btn_year; Evas_Object *year_access; + Eo *items[42]; Elm_Calendar_Weekday first_week_day; Elm_Calendar_Select_Mode select_mode;