From 0864af3230101939459cdd37d9d6f8f223202a07 Mon Sep 17 00:00:00 2001 From: Kim Shinwoo Date: Wed, 10 Oct 2012 09:37:50 +0000 Subject: [PATCH] From: Kim Shinwoo Subject: [E-devel] [patch][elementary] multibuttonentry - access feature i have attached a patch which has access feature for the multibuttonentry. it was hard time to implement access feature on the multibuttonentry than others. SVN revision: 77738 --- legacy/elementary/ChangeLog | 4 + legacy/elementary/src/bin/test_genlist.c | 2 +- .../elementary/src/lib/elc_multibuttonentry.c | 234 ++++++++++++++++++ legacy/elementary/src/lib/elm_genlist.c | 11 +- .../elementary/src/lib/elm_widget_genlist.h | 1 + 5 files changed, 249 insertions(+), 3 deletions(-) diff --git a/legacy/elementary/ChangeLog b/legacy/elementary/ChangeLog index 4e5035c89e..2957920712 100644 --- a/legacy/elementary/ChangeLog +++ b/legacy/elementary/ChangeLog @@ -587,3 +587,7 @@ * fix elm_spinner_special_value_add() * add elm_spinner_special_value_get() / del() + +2012-10-10 Shinwoo Kim (kimcinoo) + + * Add access features to multibuttonentry diff --git a/legacy/elementary/src/bin/test_genlist.c b/legacy/elementary/src/bin/test_genlist.c index 68207cbd95..d594a369a2 100644 --- a/legacy/elementary/src/bin/test_genlist.c +++ b/legacy/elementary/src/bin/test_genlist.c @@ -316,7 +316,7 @@ test_genlist(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_inf evas_object_show(bt_1500); elm_box_pack_end(bx, bt_1500); - for (i = 0; i < 2000; i++) + for (i = 0; i < 20000; i++) { gli = elm_genlist_item_append(gl, itc1, (void *)(long)i/* item data */, diff --git a/legacy/elementary/src/lib/elc_multibuttonentry.c b/legacy/elementary/src/lib/elc_multibuttonentry.c index 314aaa0966..bb1b4e3bdd 100644 --- a/legacy/elementary/src/lib/elc_multibuttonentry.c +++ b/legacy/elementary/src/lib/elc_multibuttonentry.c @@ -329,6 +329,9 @@ _elm_multibuttonentry_smart_on_focus(Evas_Object *obj) if (elm_widget_focus_get(obj)) { + // ACCESS + if ((_elm_config->access_mode == ELM_ACCESS_MODE_ON)) return EINA_TRUE; + if (sd->editable) { if ((sd->selected_it)) @@ -457,6 +460,28 @@ _button_select(Evas_Object *obj, { elm_object_focus_set(sd->entry, EINA_FALSE); evas_object_focus_set(btn, EINA_TRUE); + + // ACCESS + if (_elm_config->access_mode != ELM_ACCESS_MODE_OFF) + { + Evas_Object *ao, *po; + Eina_Strbuf *buf; + const char *part, *text; + + part = "elm.btn.text"; + po = (Evas_Object *)edje_object_part_object_get(btn, part); + ao = evas_object_data_get(po, "_part_access_obj"); + _elm_access_highlight_set(ao); + + buf = eina_strbuf_new(); + eina_strbuf_append_printf(buf, + "multi button entry item %s is selected", + edje_object_part_text_get(btn, part)); + + text = (const char*)eina_strbuf_string_steal(buf); + _elm_access_say(text); + eina_strbuf_free(buf); + } } } else @@ -562,6 +587,54 @@ _item_del_pre_hook(Elm_Object_Item *it) return EINA_TRUE; } +static void +_access_multibuttonentry_label_register(Evas_Object *obj, Eina_Bool is_access) +{ + ELM_MULTIBUTTONENTRY_DATA_GET(obj, sd); + + Evas_Object *po; + po = (Evas_Object *)edje_object_part_object_get(sd->label, "mbe.label"); + + if (is_access) + { + Evas_Object *ao; + ao = _elm_access_edje_object_part_object_register + (obj, sd->label, "mbe.label"); + _elm_access_text_set(_elm_access_object_get(ao), + ELM_ACCESS_TYPE, E_("multi button entry label")); + } + else + _elm_access_edje_object_part_object_unregister + (obj, sd->label, "mbe.label"); + + + evas_object_pass_events_set(po, !is_access); + evas_object_propagate_events_set(sd->label, !is_access); +} + +static void +_access_multibuttonentry_item_register(Evas_Object *obj, + Elm_Multibuttonentry_Item *item, + Eina_Bool is_access) +{ + if (is_access) + { + Evas_Object *ao; + ao = _elm_access_edje_object_part_object_register + (obj, item->button, "elm.btn.text"); + _elm_access_text_set(_elm_access_object_get(ao), + ELM_ACCESS_TYPE, E_("multi button entry item")); + } + else + _elm_access_edje_object_part_object_unregister + (obj, item->button, "elm.btn.text"); + + /* cannot read item->button because mouse-in event is delivered to + the multibuttonentry resize_obj which is registered as an access + object, so the mouse-in event should be blocked here */ + evas_object_propagate_events_set(item->button, !is_access); +} + static Elm_Object_Item * _button_item_add(Evas_Object *obj, const char *str, @@ -621,6 +694,24 @@ _button_item_add(Evas_Object *obj, item->vw = vw; item->visible = EINA_TRUE; + // ACCESS + if ((_elm_config->access_mode == ELM_ACCESS_MODE_ON)) + { + const char *text; + Eina_Strbuf *buf; + buf = eina_strbuf_new(); + + eina_strbuf_append_printf(buf, + "multi button entry item %s is added", + edje_object_part_text_get(item->button, "elm.btn.text")); + + text = (const char*)eina_strbuf_string_steal(buf); + _elm_access_say(text); + eina_strbuf_free(buf); + + _access_multibuttonentry_item_register(obj, item, EINA_TRUE); + } + if (func) { item->func = func; @@ -743,6 +834,9 @@ _elm_multibuttonentry_smart_event(Evas_Object *obj, { if (elm_widget_disabled_get(obj)) return EINA_FALSE; + // ACCESS + if ((_elm_config->access_mode == ELM_ACCESS_MODE_ON)) return EINA_FALSE; + return EINA_TRUE; } @@ -1281,6 +1375,10 @@ _view_init(Evas_Object *obj) _label_set(obj, ""); elm_widget_sub_object_add(obj, sd->label); + // ACCESS + if ((_elm_config->access_mode == ELM_ACCESS_MODE_ON)) + _access_multibuttonentry_label_register(obj, EINA_TRUE); + sd->entry = elm_entry_add(obj); if (!sd->entry) return; elm_entry_single_line_set(sd->entry, EINA_TRUE); @@ -1364,6 +1462,46 @@ _elm_multibuttonentry_smart_text_get(const Evas_Object *obj, else return _elm_multibuttonentry_parent_sc->text_get(obj, part); } +static char * +_access_info_cb(void *data __UNUSED__, + Evas_Object *obj, + Elm_Widget_Item *item __UNUSED__) +{ + char *ret; + Eina_Strbuf *buf; + Eina_List *l = NULL; + Elm_Multibuttonentry_Item *it; + + ELM_MULTIBUTTONENTRY_DATA_GET(obj, sd); + + if (sd->view_state == MULTIBUTTONENTRY_VIEW_GUIDETEXT) + { + if (sd->guide_text_str) return strdup(sd->guide_text_str); + return NULL; + } + + buf = eina_strbuf_new(); + + if (sd->label_str) eina_strbuf_append(buf, sd->label_str); + + int invisible_its = 0; + EINA_LIST_FOREACH (sd->items, l, it) + { + if (it->visible) + eina_strbuf_append_printf(buf, ", %s", + edje_object_part_text_get(it->button, "elm.btn.text")); + else + invisible_its++; + } + + if (invisible_its) + eina_strbuf_append_printf(buf, ", and %d more", invisible_its); + + ret = eina_strbuf_string_steal(buf); + eina_strbuf_free(buf); + return ret; +} + static void _elm_multibuttonentry_smart_add(Evas_Object *obj) { @@ -1387,6 +1525,13 @@ _elm_multibuttonentry_smart_add(Evas_Object *obj) _view_init(obj); _callbacks_register(obj); + + // ACCESS + _elm_access_object_register(obj, ELM_WIDGET_DATA(priv)->resize_obj); + _elm_access_text_set + (_elm_access_object_get(obj), ELM_ACCESS_TYPE, E_("multi button entry")); + _elm_access_callback_set + (_elm_access_object_get(obj), ELM_ACCESS_INFO, _access_info_cb, NULL); } static void @@ -1416,6 +1561,89 @@ _elm_multibuttonentry_smart_del(Evas_Object *obj) ELM_WIDGET_CLASS(_elm_multibuttonentry_parent_sc)->base.del(obj); } +static Eina_Bool +_elm_multibuttonentry_smart_focus_next(const Evas_Object *obj, + Elm_Focus_Direction dir, + Evas_Object **next) +{ + Eina_List *items = NULL; + Eina_List *l = NULL; + Elm_Multibuttonentry_Item *it; + Evas_Object *ao; + Evas_Object *po; + Eina_Bool ret = EINA_FALSE; + + ELM_MULTIBUTTONENTRY_DATA_GET(obj, sd); + + if (!elm_widget_focus_get(obj)) + { + *next = (Evas_Object *)obj; + return EINA_TRUE; + } + + if (sd->label) + { + po = (Evas_Object *)edje_object_part_object_get(sd->label, "mbe.label"); + ao = evas_object_data_get(po, "_part_access_obj"); + ret = elm_widget_focus_get(ao); + items = eina_list_append(items, ao); + } + + EINA_LIST_FOREACH (sd->items, l, it) + { + po = (Evas_Object *)edje_object_part_object_get + (it->button, "elm.btn.text"); + ao = evas_object_data_get(po, "_part_access_obj"); + ret = ret || elm_widget_focus_get(ao); + items = eina_list_append(items, ao); + } + + if (sd->entry) + { + ret = ret || elm_widget_focus_get(sd->entry); + /* elm_widget_list_focus_liset_next_get() check parent of item + because parent sd->entry is not multibuttnentry but sd->box + so append sd->box instead of sd->entry, is this proper? */ + items = eina_list_append(items, sd->box); + } + + if (ret) + return elm_widget_focus_list_next_get + (obj, items, eina_list_data_get, dir, next); + + return EINA_FALSE; +} + +static void +_access_obj_process(Evas_Object *obj, Eina_Bool is_access) +{ + Eina_List *l; + Elm_Multibuttonentry_Item *it; + + ELM_MULTIBUTTONENTRY_DATA_GET(obj, sd); + + /* label */ + _access_multibuttonentry_label_register(obj, is_access); + + /* buttons */ + EINA_LIST_FOREACH (sd->items, l, it) + _access_multibuttonentry_item_register(obj, it, is_access); +} + +static void +_elm_multibuttonentry_smart_access(Evas_Object *obj, Eina_Bool is_access) +{ + ELM_MULTIBUTTONENTRY_CHECK(obj); + ELM_MULTIBUTTONENTRY_DATA_GET(obj, sd); + + if (is_access) + ELM_WIDGET_CLASS(ELM_WIDGET_DATA(sd)->api)->focus_next = + _elm_multibuttonentry_smart_focus_next; + else + ELM_WIDGET_CLASS(ELM_WIDGET_DATA(sd)->api)->focus_next = NULL; + _access_obj_process(obj, is_access); +} + static void _elm_multibuttonentry_smart_set_user(Elm_Multibuttonentry_Smart_Class *sc) { @@ -1433,6 +1661,12 @@ _elm_multibuttonentry_smart_set_user(Elm_Multibuttonentry_Smart_Class *sc) ELM_LAYOUT_CLASS(sc)->text_set = _elm_multibuttonentry_smart_text_set; ELM_LAYOUT_CLASS(sc)->text_get = _elm_multibuttonentry_smart_text_get; ELM_LAYOUT_CLASS(sc)->sizing_eval = _elm_multibuttonentry_smart_sizing_eval; + + // ACCESS + if (_elm_config->access_mode != ELM_ACCESS_MODE_OFF) + ELM_WIDGET_CLASS(sc)->focus_next = _elm_multibuttonentry_smart_focus_next; + + ELM_WIDGET_CLASS(sc)->access = _elm_multibuttonentry_smart_access; } EAPI const Elm_Multibuttonentry_Smart_Class * diff --git a/legacy/elementary/src/lib/elm_genlist.c b/legacy/elementary/src/lib/elm_genlist.c index 9916c6bed9..3df8eb4957 100644 --- a/legacy/elementary/src/lib/elm_genlist.c +++ b/legacy/elementary/src/lib/elm_genlist.c @@ -3666,7 +3666,11 @@ _item_idle_enterer(void *data) if (sd->calc_job) ecore_job_del(sd->calc_job); sd->calc_job = ecore_job_add(_calc_job, sd); } - if (ok == ECORE_CALLBACK_CANCEL) sd->queue_idle_enterer = NULL; + if (ok == ECORE_CALLBACK_CANCEL) + { + printf("queue time: %3.3f\n", ecore_time_get() - sd->q_start); + sd->queue_idle_enterer = NULL; + } return ok; } @@ -3708,7 +3712,10 @@ _item_queue(Elm_Genlist_Smart_Data *sd, // evas_event_thaw(evas_object_evas_get(sd->obj)); // evas_event_thaw_eval(evas_object_evas_get(sd->obj)); if (!sd->queue_idle_enterer) - sd->queue_idle_enterer = ecore_idle_enterer_add(_item_idle_enterer, sd); + { + sd->q_start = ecore_time_get(); + sd->queue_idle_enterer = ecore_idle_enterer_add(_item_idle_enterer, sd); + } } /* If the application wants to know the relative item, use diff --git a/legacy/elementary/src/lib/elm_widget_genlist.h b/legacy/elementary/src/lib/elm_widget_genlist.h index 9b2f8cefc1..bc08e2100c 100644 --- a/legacy/elementary/src/lib/elm_widget_genlist.h +++ b/legacy/elementary/src/lib/elm_widget_genlist.h @@ -172,6 +172,7 @@ struct _Elm_Genlist_Smart_Data Evas_Coord reorder_old_pan_y, w, h, realminw, prev_viewport_w; Ecore_Job *update_job; + double q_start; Ecore_Idle_Enterer *queue_idle_enterer; Ecore_Idler *must_recalc_idler; Eina_List *queue;