From 7aacc9fc4b324c0f5564392bea18f45a806d5424 Mon Sep 17 00:00:00 2001 From: Kim Shinwoo Date: Wed, 12 Sep 2012 08:25:10 +0000 Subject: [PATCH] From: Kim Shinwoo Subject: [E-devel] [patch][elementary] calendar - add access feature, access - add _elm_access_edje_object_part_object_unregister(); the attachment has accessibility feature which is for the elm_calendar. and moreover.. it would be better to keep one more api for the access which name is _elm_access_edje_object_part_object_unregister(); in the case of calendar item, its text part could be set with empty value in run time(dynamically), even though it had a value (1~31) previously. so if there is an empty field(item), then previously registered item should be unregistered. the api would be useful not only this case but also others. then, please review the patch and give feedback. thanks. SVN revision: 76502 --- legacy/elementary/ChangeLog | 5 + .../data/themes/widgets/calendar.edc | 10 + legacy/elementary/src/lib/elm_access.c | 42 ++++ legacy/elementary/src/lib/elm_calendar.c | 195 ++++++++++++++++++ legacy/elementary/src/lib/elm_widget.h | 4 + .../elementary/src/lib/elm_widget_calendar.h | 3 + 6 files changed, 259 insertions(+) diff --git a/legacy/elementary/ChangeLog b/legacy/elementary/ChangeLog index 65dbf74e68..ab6a8e35ea 100644 --- a/legacy/elementary/ChangeLog +++ b/legacy/elementary/ChangeLog @@ -462,3 +462,8 @@ * When the number of item is changed, the toolbar emits the signal to theme. The theme can be changed something according the number of item. + +2012-09-12 Shinwoo Kim (kimcinoo) + + * Add access features to calendar. + diff --git a/legacy/elementary/data/themes/widgets/calendar.edc b/legacy/elementary/data/themes/widgets/calendar.edc index 090a11e11c..a4d3b6709b 100644 --- a/legacy/elementary/data/themes/widgets/calendar.edc +++ b/legacy/elementary/data/themes/widgets/calendar.edc @@ -258,6 +258,16 @@ visible: 1; \ } \ } \ + part { name: "cit_"#_pos".access"; \ + type: RECT; \ + repeat_events: 1; \ + description { state: "default" 0.0; \ + rel1.to: "cit_"#_pos".event"; \ + rel2.to: "cit_"#_pos".event"; \ + visible: 1; \ + color: 0 0 0 0; \ + } \ + } \ programs { \ program { \ name: "cit_"#_pos".go_active"; \ diff --git a/legacy/elementary/src/lib/elm_access.c b/legacy/elementary/src/lib/elm_access.c index 4de351710f..5224882df8 100644 --- a/legacy/elementary/src/lib/elm_access.c +++ b/legacy/elementary/src/lib/elm_access.c @@ -164,6 +164,9 @@ _access_obj_del_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event _elm_access_clear(ac); free(ac); } + + // _elm_access_edje_object_part_object_register(); set below object data + evas_object_data_del(obj, "_part_access_obj"); } static void @@ -506,6 +509,11 @@ _elm_access_edje_object_part_object_register(Evas_Object* obj, if (!obj || !po) return NULL; + // check previous access object + ao = evas_object_data_get(po, "_part_access_obj"); + if (ao) + _elm_access_edje_object_part_object_unregister(obj, eobj, part); + // create access object ao = _elm_access_add(obj); evas_object_event_callback_add(po, EVAS_CALLBACK_RESIZE, @@ -528,9 +536,43 @@ _elm_access_edje_object_part_object_register(Evas_Object* obj, _elm_access_callback_set(_elm_access_object_get(ao), ELM_ACCESS_INFO, _part_access_info_cb, eobj); + + // set access object + evas_object_data_set(po, "_part_access_obj", ao); + return ao; } +EAPI void +_elm_access_edje_object_part_object_unregister(Evas_Object* obj, + const Evas_Object *eobj, + const char* part) +{ + Evas_Object *ao; + Evas_Object *po = (Evas_Object *)edje_object_part_object_get(eobj, part); + + if (!obj || !po) return; + + ao = evas_object_data_get(po, "_part_access_obj"); + if (!ao) return; + + evas_object_data_del(po, "_part_access_obj"); + + // delete callbacks + evas_object_event_callback_del_full(po, EVAS_CALLBACK_RESIZE, + _content_resize, ao); + evas_object_event_callback_del_full(po, EVAS_CALLBACK_MOVE, + _content_move, ao); + + evas_object_event_callback_del_full(po, EVAS_CALLBACK_MOUSE_IN, + _access_obj_mouse_in_cb, ao); + evas_object_event_callback_del_full(po, EVAS_CALLBACK_MOUSE_OUT, + _access_obj_mouse_out_cb, ao); + evas_object_event_callback_del_full(po, EVAS_CALLBACK_DEL, + _access_obj_del_cb, ao); + evas_object_del(ao); +} + EAPI void _elm_access_object_hilight_disable(Evas *e) { diff --git a/legacy/elementary/src/lib/elm_calendar.c b/legacy/elementary/src/lib/elm_calendar.c index ff38a4f4ee..a33c098930 100644 --- a/legacy/elementary/src/lib/elm_calendar.c +++ b/legacy/elementary/src/lib/elm_calendar.c @@ -194,6 +194,97 @@ _set_month_year(Elm_Calendar_Smart_Data *sd) else elm_layout_text_set(ELM_WIDGET_DATA(sd)->obj, "month_text", ""); } +static char * +_access_info_cb(void *data __UNUSED__, + Evas_Object *obj, + Elm_Widget_Item *item __UNUSED__) +{ + char *ret; + Eina_Strbuf *buf; + buf = eina_strbuf_new(); + + eina_strbuf_append_printf(buf, "day %s", elm_widget_access_info_get(obj)); + + ret = eina_strbuf_string_steal(buf); + eina_strbuf_free(buf); + return ret; +} + +static void +_access_calendar_item_register(Evas_Object *obj) +{ + int maxdays, day, i; + char day_s[3], pname[14]; + Evas_Object *ao; + + ELM_CALENDAR_DATA_GET(obj, sd); + + day = 0; + maxdays = _maxdays_get(&sd->shown_time); + for (i = 0; i < 42; i++) + { + if ((!day) && (i == sd->first_day_it)) day = 1; + if ((day) && (day <= maxdays)) + { + snprintf(pname, sizeof(pname), "cit_%i.access", i); + + ao = _elm_access_edje_object_part_object_register + (obj, elm_layout_edje_get(obj), pname); + _elm_access_text_set(_elm_access_object_get(ao), + ELM_ACCESS_TYPE, E_("calendar item")); + _elm_access_callback_set(_elm_access_object_get(ao), + ELM_ACCESS_INFO, _access_info_cb, NULL); + + snprintf(day_s, sizeof(day_s), "%i", day++); + elm_widget_access_info_set(ao, (const char*)day_s); + } + else + { + snprintf(pname, sizeof(pname), "cit_%i.access", i); + _elm_access_edje_object_part_object_unregister + (obj, elm_layout_edje_get(obj), pname); + } + } +} + +static void +_access_calendar_spinner_register(Evas_Object *obj) +{ + Evas_Object *po; + Elm_Access_Info *ai; + ELM_CALENDAR_DATA_GET(obj, sd); + + // decrement button + sd->dec_btn_access = _elm_access_edje_object_part_object_register + (obj, elm_layout_edje_get(obj), "left_bt"); + ai = _elm_access_object_get(sd->dec_btn_access); + _elm_access_text_set(ai, ELM_ACCESS_TYPE, E_("calendar decrement button")); + + // increment button + sd->inc_btn_access = _elm_access_edje_object_part_object_register + (obj, elm_layout_edje_get(obj), "right_bt"); + ai = _elm_access_object_get(sd->inc_btn_access); + _elm_access_text_set(ai, ELM_ACCESS_TYPE, E_("calendar increment button")); + + // month text + sd->month_access = _elm_access_edje_object_part_object_register + (obj, elm_layout_edje_get(obj), "month_text"); + ai = _elm_access_object_get(sd->month_access); + _elm_access_text_set(ai, ELM_ACCESS_TYPE, E_("calendar month")); + + po = (Evas_Object *)edje_object_part_object_get + (elm_layout_edje_get(obj), "month_text"); + evas_object_pass_events_set(po, EINA_FALSE); + +} + +static void +_access_calendar_register(Evas_Object *obj) +{ + _access_calendar_spinner_register(obj); + _access_calendar_item_register(obj); +} + static void _populate(Evas_Object *obj) { @@ -310,6 +401,10 @@ _populate(Evas_Object *obj) _cit_mark(obj, i, "clear"); } + // ACCESS + if ((_elm_config->access_mode != ELM_ACCESS_MODE_OFF)) + _access_calendar_item_register(obj); + /* Set marks */ EINA_LIST_FOREACH (sd->marks, l, mark) { @@ -757,6 +852,10 @@ _elm_calendar_smart_add(Evas_Object *obj) elm_layout_theme_set(obj, "calendar", "base", elm_object_style_get(obj)); evas_object_smart_changed(obj); + + // ACCESS + if ((_elm_config->access_mode != ELM_ACCESS_MODE_OFF)) + _access_calendar_spinner_register(obj); } static void @@ -783,6 +882,96 @@ _elm_calendar_smart_del(Evas_Object *obj) ELM_WIDGET_CLASS(_elm_calendar_parent_sc)->base.del(obj); } +static Eina_Bool +_elm_calendar_smart_focus_next(const Evas_Object *obj, + Elm_Focus_Direction dir, + Evas_Object **next) +{ + int maxdays, day, i; + Eina_List *items = NULL; + Evas_Object *ao; + Evas_Object *po; + + ELM_CALENDAR_CHECK(obj) EINA_FALSE; + ELM_CALENDAR_DATA_GET(obj, sd); + + items = eina_list_append(items, sd->month_access); + items = eina_list_append(items, sd->dec_btn_access); + items = eina_list_append(items, sd->inc_btn_access); + + day = 0; + maxdays = _maxdays_get(&sd->shown_time); + 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); +} + +static void +_access_obj_process(Evas_Object *obj, Eina_Bool is_access) +{ + int maxdays, day, i; + + ELM_CALENDAR_DATA_GET(obj, sd); + + if (is_access) + _access_calendar_register(obj); + else + { + day = 0; + maxdays = _maxdays_get(&sd->shown_time); + 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); + + _elm_access_edje_object_part_object_unregister + (obj, elm_layout_edje_get(obj), pname); + } + } + + if (sd->dec_btn_access) + _elm_access_edje_object_part_object_unregister + (obj, elm_layout_edje_get(obj), "left_bt"); + if (sd->inc_btn_access) + _elm_access_edje_object_part_object_unregister + (obj, elm_layout_edje_get(obj), "right_bt"); + if (sd->month_access) + _elm_access_edje_object_part_object_unregister + (obj, elm_layout_edje_get(obj), "month_text"); + } +} + +static void +_access_hook(Evas_Object *obj, Eina_Bool is_access) +{ + ELM_CALENDAR_CHECK(obj); + ELM_CALENDAR_DATA_GET(obj, sd); + + if (is_access) + ELM_WIDGET_CLASS(ELM_WIDGET_DATA(sd)->api)->focus_next = + _elm_calendar_smart_focus_next; + else + ELM_WIDGET_CLASS(ELM_WIDGET_DATA(sd)->api)->focus_next = NULL; + _access_obj_process(obj, is_access); +} + static void _elm_calendar_smart_set_user(Elm_Calendar_Smart_Class *sc) { @@ -798,6 +987,12 @@ _elm_calendar_smart_set_user(Elm_Calendar_Smart_Class *sc) ELM_WIDGET_CLASS(sc)->focus_direction = NULL; ELM_LAYOUT_CLASS(sc)->sizing_eval = _elm_calendar_smart_sizing_eval; + + // ACCESS + if (_elm_config->access_mode != ELM_ACCESS_MODE_OFF) + ELM_WIDGET_CLASS(sc)->focus_next = _elm_calendar_smart_focus_next; + + ELM_WIDGET_CLASS(sc)->access = _access_hook; } EAPI const Elm_Calendar_Smart_Class * diff --git a/legacy/elementary/src/lib/elm_widget.h b/legacy/elementary/src/lib/elm_widget.h index f49c419465..5dcebdfe71 100644 --- a/legacy/elementary/src/lib/elm_widget.h +++ b/legacy/elementary/src/lib/elm_widget.h @@ -547,6 +547,7 @@ typedef Eina_Bool (*Elm_Widget_Del_Pre_Cb)(void *data); typedef char *(*Elm_Access_Content_Cb)(void *data, Evas_Object *obj, Elm_Widget_Item *item); typedef void (*Elm_Access_On_Highlight_Cb)(void *data); +typedef void (*Elm_Access_Activate_Cb)(Evas_Object *obj, void *data); struct _Elm_Access_Item { @@ -562,6 +563,8 @@ struct _Elm_Access_Info Ecore_Timer *delay_timer; void *on_highlight_data; Elm_Access_On_Highlight_Cb on_highlight; + void *activate_data; + Elm_Access_Activate_Cb activate; }; EAPI void _elm_access_clear(Elm_Access_Info *ac); @@ -581,6 +584,7 @@ EAPI void _elm_access_item_register(Elm_Widget_Item *item, Evas_Obje EAPI Eina_Bool _elm_access_2nd_click_timeout(Evas_Object *obj); EAPI void _elm_access_highlight_set(Evas_Object* obj); EAPI Evas_Object * _elm_access_edje_object_part_object_register(Evas_Object *obj, const Evas_Object *partobj, const char* part); +EAPI void _elm_access_edje_object_part_object_unregister(Evas_Object* obj, const Evas_Object *eobj, const char* part); EAPI void _elm_access_widget_item_register(Elm_Widget_Item *item); EAPI void _elm_access_widget_item_unregister(Elm_Widget_Item *item); EAPI void _elm_access_on_highlight_hook_set(Elm_Access_Info *ac, Elm_Access_On_Highlight_Cb func, void *data); diff --git a/legacy/elementary/src/lib/elm_widget_calendar.h b/legacy/elementary/src/lib/elm_widget_calendar.h index ba7e507330..a6fe78eff7 100644 --- a/legacy/elementary/src/lib/elm_widget_calendar.h +++ b/legacy/elementary/src/lib/elm_widget_calendar.h @@ -142,6 +142,9 @@ struct _Elm_Calendar_Smart_Data struct tm current_time, selected_time, shown_time; Day_Color day_color[42]; // EINA_DEPRECATED Elm_Calendar_Select_Mode select_mode; + Evas_Object *inc_btn_access; + Evas_Object *dec_btn_access; + Evas_Object *month_access; Eina_Bool selected : 1; Elm_Calendar_Selectable selectable; };