From: Kim Shinwoo <kimcinoo.efl@gmail.com>

Subject: [E-devel] [patch][elementary] segment_control, spinner -
accessibility feature

the attached patch provides accessibility features for segment_control
and spinner.



SVN revision: 75497
This commit is contained in:
Kim Shinwoo 2012-08-21 10:08:56 +00:00 committed by Carsten Haitzler
parent faa6d2e91f
commit ff071585ac
5 changed files with 279 additions and 1 deletions

View File

@ -387,7 +387,7 @@
2012-08-20 Shinwoo Kim (kimcinoo)
* Patch in incomplte access support in datetime.
* Patch in incomplete access support in datetime.
2012-08-21 Carsten Haitzler (The Rasterman)
@ -396,3 +396,8 @@
of course twiddle with the norender state too), so add this in.
elm_win_norender_push(), elm_win_norender_pop(),
elm_win_norender_get() and elm_win_render() added.
2012-08-21 Shinwoo Kim (kimcinoo)
* Patch in incomplete access support in segment control and spinner

View File

@ -355,6 +355,20 @@ group { name: "elm/spinner/base/default";
visible: 1;
}
}
part { name: "access_text";
type: RECT;
repeat_events: 1;
description { state: "default" 0.0;
color: 0 0 0 0;
rel1.to: "elm.text";
rel2.to: "elm.text";
}
description { state: "disabled" 0.0;
color: 0 0 0 0;
rel1.to: "disabler";
rel2.to: "disabler";
}
}
}
programs {
program { name: "text_show";
@ -504,6 +518,7 @@ group { name: "elm/spinner/base/default";
target: "right_over1";
target: "right_over2";
target: "disabler";
target: "access_text";
after: "disable_text";
}
program { name: "disable_text";
@ -534,6 +549,7 @@ group { name: "elm/spinner/base/default";
target: "right_over1";
target: "right_over2";
target: "disabler";
target: "access_text";
after: "enable_text";
}
program { name: "enable_text";
@ -892,6 +908,20 @@ group { name: "elm/spinner/base/vertical";
visible: 1;
}
}
part { name: "access_text";
type: RECT;
repeat_events: 1;
description { state: "default" 0.0;
color: 0 0 0 0;
rel1.to: "elm.text";
rel2.to: "elm.text";
}
description { state: "disabled" 0.0;
color: 0 0 0 0;
rel1.to: "disabler";
rel2.to: "disabler";
}
}
}
programs {
program { name: "text_show";
@ -963,6 +993,7 @@ group { name: "elm/spinner/base/vertical";
target: "down_bt";
target: "up_bt";
target: "disabler";
target: "access_text";
after: "disable_text";
}
program { name: "disable_text";
@ -989,6 +1020,7 @@ group { name: "elm/spinner/base/vertical";
target: "down_bt";
target: "up_bt";
target: "disabler";
target: "access_text";
after: "enable_text";
}
program { name: "enable_text";

View File

@ -437,6 +437,53 @@ _item_del_pre_hook(Elm_Object_Item *it)
return EINA_TRUE;
}
static char *
_access_info_cb(void *data,
Evas_Object *obj __UNUSED__,
Elm_Widget_Item *item __UNUSED__)
{
const char *txt = NULL;
Elm_Segment_Item *it = (Elm_Segment_Item *)data;
ELM_SEGMENT_CONTROL_ITEM_CHECK_OR_RETURN(it, NULL);
if (!txt) txt = it->label;
if (txt) return strdup(txt);
return NULL;
}
static char *
_access_state_cb(void *data,
Evas_Object *obj __UNUSED__,
Elm_Widget_Item *item __UNUSED__)
{
Elm_Segment_Item *it = (Elm_Segment_Item *)data;
ELM_SEGMENT_CONTROL_ITEM_CHECK_OR_RETURN(it, NULL);
ELM_SEGMENT_CONTROL_DATA_GET(WIDGET(it), sd);
if (ELM_WIDGET_DATA(sd)->disabled)
return strdup(E_("State: Disabled"));
if (it == sd->selected_item)
return strdup(E_("State: Selected"));
else
return strdup(E_("State: Unselected"));
}
static void
_access_widget_item_register(Elm_Segment_Item *it)
{
Elm_Access_Info *ai;
_elm_access_widget_item_register((Elm_Widget_Item *)it);
ai = _elm_access_object_get(it->base.access_obj);
_elm_access_text_set(ai, ELM_ACCESS_TYPE, E_("Segment Control Item"));
_elm_access_callback_set(ai, ELM_ACCESS_INFO, _access_info_cb, it);
_elm_access_callback_set(ai, ELM_ACCESS_STATE, _access_state_cb, it);
}
static Elm_Segment_Item *
_item_new(Evas_Object *obj,
Evas_Object *icon,
@ -479,6 +526,10 @@ _item_new(Evas_Object *obj,
(VIEW(it), EVAS_CALLBACK_MOUSE_UP, _on_mouse_up, it);
evas_object_show(VIEW(it));
// ACCESS
if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
_access_widget_item_register(it);
return it;
}
@ -516,6 +567,53 @@ _elm_segment_control_smart_del(Evas_Object *obj)
ELM_WIDGET_CLASS(_elm_segment_control_parent_sc)->base.del(obj);
}
static Eina_Bool
_elm_segment_control_smart_focus_next(const Evas_Object *obj,
Elm_Focus_Direction dir,
Evas_Object **next)
{
Eina_List *items = NULL;
Eina_List *l;
Elm_Segment_Item *it;
ELM_SEGMENT_CONTROL_CHECK(obj) EINA_FALSE;
ELM_SEGMENT_CONTROL_DATA_GET(obj, sd);
EINA_LIST_FOREACH(sd->items, l, it)
items = eina_list_append(items, it->base.access_obj);
return elm_widget_focus_list_next_get
(obj, items, eina_list_data_get, dir, next);
}
static void
_access_obj_process(Elm_Segment_Control_Smart_Data * sd, Eina_Bool is_access)
{
Eina_List *l;
Elm_Segment_Item *it;
EINA_LIST_FOREACH(sd->items, l, it)
{
if (is_access) _access_widget_item_register(it);
else
_elm_access_widget_item_unregister((Elm_Widget_Item *)it);
}
}
static void
_access_hook(Evas_Object *obj, Eina_Bool is_access)
{
ELM_SEGMENT_CONTROL_CHECK(obj);
ELM_SEGMENT_CONTROL_DATA_GET(obj, sd);
if (is_access)
ELM_WIDGET_CLASS(ELM_WIDGET_DATA(sd)->api)->focus_next =
_elm_segment_control_smart_focus_next;
else
ELM_WIDGET_CLASS(ELM_WIDGET_DATA(sd)->api)->focus_next = NULL;
_access_obj_process(sd, is_access);
}
static void
_elm_segment_control_smart_set_user(Elm_Segment_Control_Smart_Class *sc)
{
@ -534,6 +632,12 @@ _elm_segment_control_smart_set_user(Elm_Segment_Control_Smart_Class *sc)
ELM_WIDGET_CLASS(sc)->focus_direction = NULL;
ELM_LAYOUT_CLASS(sc)->sizing_eval = _elm_segment_control_smart_sizing_eval;
// ACCESS
if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
ELM_WIDGET_CLASS(sc)->focus_next = _elm_segment_control_smart_focus_next;
ELM_WIDGET_CLASS(sc)->access = _access_hook;
}
EAPI const Elm_Segment_Control_Smart_Class *

View File

@ -479,6 +479,78 @@ _elm_spinner_smart_on_focus(Evas_Object *obj)
return EINA_TRUE;
}
static char *
_access_info_cb(void *data,
Evas_Object *obj,
Elm_Widget_Item *item __UNUSED__)
{
Evas_Object *spinner;
const char *txt = elm_widget_access_info_get(obj);
spinner = ELM_WIDGET_DATA(data)->obj;
if (!txt) txt = elm_layout_text_get(spinner, "elm.text");
if (txt) return strdup(txt);
return NULL;
}
static char *
_access_state_cb(void *data,
Evas_Object *obj __UNUSED__,
Elm_Widget_Item *item __UNUSED__)
{
if (elm_widget_disabled_get(ELM_WIDGET_DATA(data)->obj))
return strdup(E_("State: Disabled"));
return NULL;
}
static void
_access_spinner_register(Evas_Object *obj)
{
Elm_Access_Info *ai;
const char* increment_part;
const char* decrement_part;
ELM_SPINNER_DATA_GET(obj, sd);
if (!strcmp(elm_widget_style_get(obj), "vertical"))
{
increment_part = "up_bt";
decrement_part = "down_bt";
}
else
{
increment_part = "right_bt";
decrement_part = "left_bt";
}
// increment button
sd->increment_btn_access =
_elm_access_edje_object_part_object_register
(obj, elm_layout_edje_get(obj), increment_part);
ai = _elm_access_object_get(sd->increment_btn_access);
_elm_access_text_set(ai, ELM_ACCESS_TYPE, E_("spinner increment button"));
// decrement button
sd->decrement_btn_access =
_elm_access_edje_object_part_object_register
(obj, elm_layout_edje_get(obj), decrement_part);
ai = _elm_access_object_get(sd->decrement_btn_access);
_elm_access_text_set(ai, ELM_ACCESS_TYPE, E_("spinner decrement button"));
// spinner label
sd->access_obj = _elm_access_edje_object_part_object_register
(obj, elm_layout_edje_get(obj), "access_text");
ai = _elm_access_object_get(sd->access_obj);
_elm_access_text_set(ai, ELM_ACCESS_TYPE, E_("spinner"));
_elm_access_callback_set(ai, ELM_ACCESS_INFO, _access_info_cb, sd);
_elm_access_callback_set(ai, ELM_ACCESS_STATE, _access_state_cb, sd);
}
static void
_elm_spinner_smart_add(Evas_Object *obj)
{
@ -527,6 +599,10 @@ _elm_spinner_smart_add(Evas_Object *obj)
elm_widget_can_focus_set(obj, EINA_TRUE);
elm_layout_sizing_eval(obj);
// ACCESS
if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
_access_spinner_register(obj);
}
static void
@ -551,6 +627,56 @@ _elm_spinner_smart_del(Evas_Object *obj)
ELM_WIDGET_CLASS(_elm_spinner_parent_sc)->base.del(obj);
}
static Eina_Bool
_elm_spinner_smart_theme(Evas_Object *obj)
{
Eina_Bool ret;
ret = elm_layout_theme_set(obj, "spinner", "base",
elm_widget_style_get(obj));
if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
_access_spinner_register(obj);
return ret;
}
static Eina_Bool
_elm_spinner_smart_focus_next(const Evas_Object *obj,
Elm_Focus_Direction dir,
Evas_Object **next)
{
Eina_List *items = NULL;
ELM_SPINNER_CHECK(obj) EINA_FALSE;
ELM_SPINNER_DATA_GET(obj, sd);
items = eina_list_append(items, sd->access_obj);
items = eina_list_append(items, sd->decrement_btn_access);
items = eina_list_append(items, sd->increment_btn_access);
return elm_widget_focus_list_next_get
(obj, items, eina_list_data_get, dir, next);
}
static void
_access_hook(Evas_Object *obj, Eina_Bool is_access)
{
ELM_SPINNER_CHECK(obj);
ELM_SPINNER_DATA_GET(obj, sd);
if (is_access)
{
ELM_WIDGET_CLASS(ELM_WIDGET_DATA(sd)->api)->focus_next =
_elm_spinner_smart_focus_next;
_access_spinner_register(obj);
}
else
{
ELM_WIDGET_CLASS(ELM_WIDGET_DATA(sd)->api)->focus_next = NULL;
//TODO: unregister edje part object
}
}
static void
_elm_spinner_smart_set_user(Elm_Spinner_Smart_Class *sc)
{
@ -565,6 +691,14 @@ _elm_spinner_smart_set_user(Elm_Spinner_Smart_Class *sc)
ELM_WIDGET_CLASS(sc)->event = _elm_spinner_smart_event;
ELM_LAYOUT_CLASS(sc)->sizing_eval = _elm_spinner_smart_sizing_eval;
ELM_WIDGET_CLASS(sc)->theme = _elm_spinner_smart_theme;
// ACCESS
if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
ELM_WIDGET_CLASS(sc)->focus_next = _elm_spinner_smart_focus_next;
ELM_WIDGET_CLASS(sc)->access = _access_hook;
}
EAPI const Elm_Spinner_Smart_Class *

View File

@ -134,6 +134,9 @@ struct _Elm_Spinner_Smart_Data
int round;
Ecore_Timer *delay, *spin;
Eina_List *special_values;
Evas_Object *access_obj;
Evas_Object *increment_btn_access;
Evas_Object *decrement_btn_access;
Eina_Bool entry_visible : 1;
Eina_Bool dragging : 1;