From: Shinwoo Kim Date: Tue, 16 Apr 2013 08:33:11 +0000 (+0900) Subject: [access][plug] add access feature X-Git-Tag: submit/tizen_2.1/20130514.052447~10 X-Git-Url: http://review.tizen.org/git/?p=framework%2Fuifw%2Felementary.git;a=commitdiff_plain;h=36910f192953709d4b28b9ce40ba2f1f5aece3f7 [access][plug] add access feature --- diff --git a/src/lib/elm_access.c b/src/lib/elm_access.c index 35ca4e2..167ccda 100644 --- a/src/lib/elm_access.c +++ b/src/lib/elm_access.c @@ -28,7 +28,7 @@ static Eina_Bool mouse_event_enable = EINA_TRUE; static Eina_Bool read_mode = EINA_FALSE; static Evas_Coord_Point offset; static Evas_Object *s_parent; /* scrollable parent */ -static Elm_Access_Action_Type action_type = ELM_ACCESS_ACTION_FIRST; +static Elm_Access_Action_Type action_by = ELM_ACCESS_ACTION_FIRST; static Evas_Object * _elm_access_add(Evas_Object *parent); @@ -64,11 +64,11 @@ _elm_access_smart_activate(Evas_Object *obj, Elm_Activate act) break; case ELM_ACTIVATE_UP: - type = ELM_ACCESS_ACTION_VALUE_CHANGE; + type = ELM_ACCESS_ACTION_UP; break; case ELM_ACTIVATE_DOWN: - type = ELM_ACCESS_ACTION_VALUE_CHANGE; + type = ELM_ACCESS_ACTION_DOWN; break; case ELM_ACTIVATE_RIGHT: @@ -501,16 +501,27 @@ _elm_access_highlight_object_scroll(Evas_Object *obj, int type, int x, int y) static Eina_Bool _access_action_callback_call(Evas_Object *obj, Elm_Access_Action_Type type, - void *data) + Elm_Access_Action_Info *action_info) { + Elm_Access_Action_Info *ai = NULL; Action_Info *a; Eina_Bool ret; ret = EINA_FALSE; a = evas_object_data_get(obj, "_elm_access_action_info"); + if (!action_info) + { + ai = calloc(1, sizeof(Elm_Access_Action_Info)); + action_info = ai; + } + + action_info->action_type = type; + if (a && (a->fn[type].cb)) - ret = a->fn[type].cb(a->fn[type].user_data, obj, data); + ret = a->fn[type].cb(a->fn[type].user_data, obj, action_info); + + if (ai) free(ai); return ret; } @@ -558,12 +569,13 @@ _access_highlight_next_get(Evas_Object *obj, Elm_Focus_Direction dir) if (!_access_action_callback_call(ho, type, NULL)) { - /* change highlight object */ - action_type = type; + /* this value is used in _elm_access_object_highlight(); + to inform the target object of how to get highlight */ + action_by = type; _elm_access_highlight_set(target); - action_type = ELM_ACCESS_ACTION_FIRST; + action_by = ELM_ACCESS_ACTION_FIRST; } } @@ -724,12 +736,12 @@ _elm_access_highlight_cycle(Evas_Object *obj, Elm_Focus_Direction dir) else type = ELM_ACCESS_ACTION_HIGHLIGHT_PREV; - action_type = type; + action_by = type; if (!_access_action_callback_call(ho, type, NULL)) elm_widget_focus_cycle(obj, dir); - action_type = ELM_ACCESS_ACTION_FIRST; + action_by = ELM_ACCESS_ACTION_FIRST; _elm_access_read_mode_set(EINA_FALSE); } @@ -863,7 +875,7 @@ _elm_access_object_hilight(Evas_Object *obj) /* use callback, should an access object do below every time when * a window gets a client message ECORE_X_ATOM_E_ILLMUE_ACTION_READ? */ a = calloc(1, sizeof(Elm_Access_Action_Info)); - a->action_type = action_type; + a->action_by = action_by; if (!_access_action_callback_call(obj, ELM_ACCESS_ACTION_HIGHLIGHT, a)) evas_object_show(o); else @@ -1312,10 +1324,14 @@ elm_access_action(Evas_Object *obj, const Elm_Access_Action_Type type, void *act _elm_access_highlight_object_activate(obj, ELM_ACTIVATE_DEFAULT); break; - case ELM_ACCESS_ACTION_VALUE_CHANGE: + case ELM_ACCESS_ACTION_UP: _elm_access_highlight_object_activate(obj, ELM_ACTIVATE_UP); break; + case ELM_ACCESS_ACTION_DOWN: + _elm_access_highlight_object_activate(obj, ELM_ACTIVATE_DOWN); + break; + case ELM_ACCESS_ACTION_SCROLL: _elm_access_highlight_object_scroll(obj, a->mouse_type, a->x, a->y); break; diff --git a/src/lib/elm_access.h b/src/lib/elm_access.h index 667b18b..72138d2 100644 --- a/src/lib/elm_access.h +++ b/src/lib/elm_access.h @@ -6,6 +6,8 @@ * */ +#define MSG_DOMAIN_CONTROL_ACCESS (int)ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL + enum _Elm_Access_Info_Type { ELM_ACCESS_INFO_FIRST = -1, @@ -50,9 +52,11 @@ enum _Elm_Access_Action_Type ELM_ACCESS_ACTION_HIGHLIGHT_NEXT, /* set highlight to next object */ ELM_ACCESS_ACTION_HIGHLIGHT_PREV, /* set highlight to previous object */ ELM_ACCESS_ACTION_ACTIVATE, /* activate a highlight object */ - ELM_ACCESS_ACTION_VALUE_CHANGE, /* change value of highlight object */ + ELM_ACCESS_ACTION_VALUE_CHANGE, /* TODO: deprecate this */ ELM_ACCESS_ACTION_SCROLL, /* scroll if one of highlight object parents * is scrollable */ + ELM_ACCESS_ACTION_UP, /* change value up of highlight object */ + ELM_ACCESS_ACTION_DOWN, /* change value down of highlight object */ ELM_ACCESS_ACTION_BACK, /* go back to a previous view ex: pop naviframe item */ ELM_ACCESS_ACTION_READ, /* highlight an object */ @@ -74,6 +78,7 @@ struct _Elm_Access_Action_Info 2: mouse up */ Elm_Access_Action_Type action_type; + Elm_Access_Action_Type action_by; Eina_Bool highlight_cycle : 1; }; diff --git a/src/lib/elm_conform.c b/src/lib/elm_conform.c index b2b359d..66250db 100644 --- a/src/lib/elm_conform.c +++ b/src/lib/elm_conform.c @@ -393,20 +393,30 @@ static const char PLUG_KEY[] = "__Plug_Ecore_Evas"; #define MSG_ID_INDICATOR_TYPE 0X1005 static void -_plug_msg_handle(Ecore_Evas *ee, int msg_domain, int msg_id, void *data, int size) +_plug_msg_handle(void *data, Evas_Object *obj, void *event_info) { - Evas_Object *conformant; + Evas_Object *conformant = data; + Elm_Plug_Message *pm = event_info; + int msg_domain = 0; + int msg_id = 0; + void *msg_data = NULL; + int msg_data_size = 0; + + if (!conformant) return; + ELM_CONFORMANT_CHECK(conformant) ; + ELM_CONFORMANT_DATA_GET(conformant, sd); + msg_domain = pm->msg_domain; + msg_id = pm->msg_id; + msg_data = pm->data; + msg_data_size = pm->size; - if (!data) return; - DBG("Receive msg from plug ee=%p msg_domain=%x msg_id=%x size=%d", ee, msg_domain, msg_id, size); + DBG("Receive msg from plug msg_domain=%x msg_id=%x size=%d", msg_domain, msg_id, msg_data_size); //get plug object form ee - conformant = (Evas_Object *)ecore_evas_data_get(ee, CONFORMANT_KEY); - ELM_CONFORMANT_DATA_GET(conformant, sd); if (msg_domain == MSG_DOMAIN_CONTROL_INDICATOR) { if (msg_id == MSG_ID_INDICATOR_REPEAT_EVENT) { - int *repeat = data; + int *repeat = msg_data; DBG("Receive repeat event change message:(%d)", *repeat); if (1 == *repeat) evas_object_repeat_events_set(sd->landscape_indicator, EINA_TRUE); @@ -415,7 +425,7 @@ _plug_msg_handle(Ecore_Evas *ee, int msg_domain, int msg_id, void *data, int siz } if (msg_id == MSG_ID_INDICATOR_TYPE) { - Elm_Win_Indicator_Type_Mode *indi_t_mode = data; + Elm_Win_Indicator_Type_Mode *indi_t_mode = msg_data; Evas_Object *win = elm_widget_top_get(conformant); DBG("Receive indicator type change message:(%d)", *indi_t_mode); elm_win_indicator_type_set(win, *indi_t_mode); @@ -453,13 +463,10 @@ _create_portrait_indicator(Evas_Object *obj) } //callback to deal with extn socket message - indicator_ee = ecore_evas_object_ecore_evas_get(elm_plug_image_object_get(port_indicator)); - DBG("This is portrait indicator's ee=%p.", indicator_ee); - ecore_evas_callback_msg_handle_set(indicator_ee, _plug_msg_handle); - ecore_evas_data_set(indicator_ee, CONFORMANT_KEY, obj); + evas_object_smart_callback_add(port_indicator, "message.received", _plug_msg_handle, obj); DBG("The rotation value of portrait indicator was changed:(%d)", sd->rot); - ecore_evas_msg_parent_send(indicator_ee, MSG_DOMAIN_CONTROL_INDICATOR, MSG_ID_INDICATOR_ROTATION, &(sd->rot), sizeof(int)); + elm_plug_msg_send(port_indicator, MSG_DOMAIN_CONTROL_INDICATOR, MSG_ID_INDICATOR_ROTATION, &(sd->rot), sizeof(int)); elm_widget_sub_object_add(obj, port_indicator); evas_object_smart_callback_add(port_indicator, "image.deleted", _port_indicator_disconnected, obj); @@ -500,12 +507,10 @@ _create_landscape_indicator(Evas_Object *obj) } //callback to deal with extn socket message - indicator_ee = ecore_evas_object_ecore_evas_get(elm_plug_image_object_get(land_indicator)); - ecore_evas_data_set(indicator_ee, CONFORMANT_KEY, obj); - DBG("This is landscape indicator's ee=%p.", indicator_ee); - ecore_evas_callback_msg_handle_set(indicator_ee, _plug_msg_handle); + evas_object_smart_callback_add(land_indicator, "message.received", _plug_msg_handle, obj); DBG("The rotation value of landscape indicator was changed:(%d)", sd->rot); - ecore_evas_msg_parent_send(indicator_ee, MSG_DOMAIN_CONTROL_INDICATOR, MSG_ID_INDICATOR_ROTATION, &(sd->rot), sizeof(int)); + + elm_plug_msg_send(land_indicator, MSG_DOMAIN_CONTROL_INDICATOR, MSG_ID_INDICATOR_ROTATION, &(sd->rot), sizeof(int)); elm_widget_sub_object_add(obj, land_indicator); evas_object_smart_callback_add(land_indicator, "image.deleted",_land_indicator_disconnected, obj); @@ -1020,9 +1025,15 @@ _elm_conformant_smart_del(Evas_Object *obj) if (sd->port_indi_timer) ecore_timer_del(sd->port_indi_timer); if (sd->land_indi_timer) ecore_timer_del(sd->land_indi_timer); if (sd->portrait_indicator) - evas_object_del(sd->portrait_indicator); + { + evas_object_smart_callback_del(sd->portrait_indicator, "message.received", _plug_msg_handle); + evas_object_del(sd->portrait_indicator); + } if (sd->landscape_indicator) - evas_object_del(sd->landscape_indicator); + { + evas_object_smart_callback_del(sd->landscape_indicator, "message.received", _plug_msg_handle); + evas_object_del(sd->landscape_indicator); + } top = elm_widget_top_get(obj); evas_object_data_set(top, "\377 elm,conformant", NULL); diff --git a/src/lib/elm_plug.c b/src/lib/elm_plug.c index 63666bc..800136a 100644 --- a/src/lib/elm_plug.c +++ b/src/lib/elm_plug.c @@ -8,9 +8,11 @@ static const char PLUG_KEY[] = "__Plug_Ecore_Evas"; static const char SIG_CLICKED[] = "clicked"; static const char SIG_IMAGE_DELETED[] = "image.deleted"; +static const char SIG_MESSAGE_RECEIVED[] = "message.received"; static const Evas_Smart_Cb_Description _smart_callbacks[] = { {SIG_CLICKED, ""}, {SIG_IMAGE_DELETED, ""}, + {SIG_MESSAGE_RECEIVED, ""}, {NULL, NULL} }; @@ -50,6 +52,64 @@ _elm_plug_smart_theme(Evas_Object *obj) return EINA_TRUE; } +static Eina_Bool +_access_action_release_cb(void *data __UNUSED__, + Evas_Object *obj __UNUSED__, + void *action_info __UNUSED__) +{ + return EINA_FALSE; +} + +static void +_elm_plug_ecore_evas_msg_handle(Ecore_Evas *ee, int msg_domain, int msg_id, void *data, int size) +{ + Evas_Object *plug, *parent; + Elm_Plug_Message pm; + + if (!data) return; + DBG("Elm plug receive msg from socket ee=%p msg_domain=%x msg_id=%x size=%d", ee, msg_domain, msg_id, size); + //get plug object form ee + plug = (Evas_Object *)ecore_evas_data_get(ee, PLUG_KEY); + ELM_PLUG_CHECK(plug); + pm.msg_domain = msg_domain; + pm.msg_id = msg_id; + pm.data = data; + pm.size = size; + + evas_object_smart_callback_call(plug, SIG_MESSAGE_RECEIVED, &pm); + + /* get message from parent */ + if (msg_domain == MSG_DOMAIN_CONTROL_ACCESS) + { + if (msg_id == ELM_ACCESS_ACTION_HIGHLIGHT_NEXT || + msg_id == ELM_ACCESS_ACTION_HIGHLIGHT_PREV) + { + elm_access_action_cb_set(plug, msg_id, + _access_action_release_cb, NULL); + + parent = plug; + do + { + ELM_WIDGET_DATA_GET(parent, sd); + if (sd->highlight_root) + { + /* change highlight root */ + plug = parent; + break; + } + plug = parent; + parent = elm_widget_parent_get(parent); + } + while (parent); + + if (msg_id == ELM_ACCESS_ACTION_HIGHLIGHT_NEXT) + _elm_access_highlight_cycle(plug, ELM_FOCUS_NEXT); + else + _elm_access_highlight_cycle(plug, ELM_FOCUS_PREVIOUS); + } + } +} + static void _on_mouse_up(void *data, Evas *e __UNUSED__, @@ -85,12 +145,72 @@ _elm_plug_smart_add(Evas_Object *obj) _sizing_eval(obj); } +static Ecore_Evas* +_elm_plug_ecore_evas_get(Evas_Object *obj) +{ + Ecore_Evas *ee = NULL; + Evas_Object *plug_img = NULL; + + ELM_PLUG_CHECK(obj) NULL; + + plug_img = elm_plug_image_object_get(obj); + if (!plug_img) return NULL; + + ee = ecore_evas_object_ecore_evas_get(plug_img); + return ee; +} + +static Eina_Bool +_elm_plug_smart_activate(Evas_Object *obj, Elm_Activate act) +{ + Ecore_Evas *ee = NULL; + Elm_Access_Action_Info *action_info = NULL; + int msg_id = ELM_ACCESS_ACTION_FIRST; + + if (act != ELM_ACTIVATE_DEFAULT && + act != ELM_ACTIVATE_UP && + act != ELM_ACTIVATE_DOWN) return EINA_FALSE; + + ee = _elm_plug_ecore_evas_get(obj); + if (!ee) return EINA_FALSE; + + switch (act) + { + case ELM_ACTIVATE_DEFAULT: + msg_id = ELM_ACCESS_ACTION_ACTIVATE; + break; + + case ELM_ACTIVATE_UP: + msg_id = ELM_ACCESS_ACTION_UP; + break; + + case ELM_ACTIVATE_DOWN: + msg_id = ELM_ACCESS_ACTION_DOWN; + break; + + default: + break; + } + + if (msg_id == ELM_ACCESS_ACTION_FIRST) return EINA_FALSE; + + action_info = calloc(1, sizeof(Elm_Access_Action_Info)); + action_info->action_type = msg_id; + + ecore_evas_msg_parent_send(ee, MSG_DOMAIN_CONTROL_ACCESS, + msg_id, &action_info, sizeof(Elm_Access_Action_Info)); + + free(action_info); + return EINA_TRUE; +} + static void _elm_plug_smart_set_user(Elm_Plug_Smart_Class *sc) { ELM_WIDGET_CLASS(sc)->base.add = _elm_plug_smart_add; ELM_WIDGET_CLASS(sc)->theme = _elm_plug_smart_theme; + ELM_WIDGET_CLASS(sc)->activate = _elm_plug_smart_activate; } EAPI const Elm_Plug_Smart_Class * @@ -108,6 +228,41 @@ elm_plug_smart_class_get(void) return class; } +static Eina_Bool +_access_action_highlight_next_cb(void *data __UNUSED__, + Evas_Object *obj, + void *action_info) +{ + Ecore_Evas *ee = NULL; + Elm_Access_Action_Info *ai = action_info; + + ee = _elm_plug_ecore_evas_get(obj); + if (!ee) return EINA_TRUE; + + ecore_evas_msg_parent_send(ee, MSG_DOMAIN_CONTROL_ACCESS, + ai->action_type, + ai, sizeof(Elm_Access_Action_Info)); + return EINA_TRUE; +} + +static Eina_Bool +_access_action_highlight_cb(void *data __UNUSED__, + Evas_Object *obj, void *action_info) +{ + Ecore_Evas *ee = NULL; + + ee = _elm_plug_ecore_evas_get(obj); + if (!ee) return EINA_FALSE; + + elm_access_action_cb_set(obj, ELM_ACCESS_ACTION_HIGHLIGHT_NEXT, + _access_action_highlight_next_cb, NULL); + + ecore_evas_msg_parent_send(ee, MSG_DOMAIN_CONTROL_ACCESS, + ELM_ACCESS_ACTION_HIGHLIGHT, + action_info, sizeof(Elm_Access_Action_Info)); + return EINA_FALSE; +} + EAPI Evas_Object * elm_plug_add(Evas_Object *parent) { @@ -124,6 +279,10 @@ elm_plug_add(Evas_Object *parent) if (!elm_widget_sub_object_add(parent, obj)) ERR("could not add %p as sub object of %p", obj, parent); + _elm_access_object_register(obj, ELM_WIDGET_DATA(sd)->resize_obj); + elm_access_action_cb_set(obj, ELM_ACCESS_ACTION_HIGHLIGHT, + _access_action_highlight_cb, NULL); + return obj; } @@ -157,8 +316,29 @@ elm_plug_connect(Evas_Object *obj, ecore_evas_data_set(ee, PLUG_KEY, obj); ecore_evas_callback_delete_request_set(ee, _elm_plug_disconnected); + ecore_evas_callback_msg_handle_set(ee, _elm_plug_ecore_evas_msg_handle); return EINA_TRUE; } else return EINA_FALSE; } + +EAPI Eina_Bool +elm_plug_msg_send(Evas_Object *obj, + int msg_domain, + int msg_id, + void *data, int size) +{ + Ecore_Evas *ee = NULL; + Evas_Object *plug_img = NULL; + + ELM_PLUG_CHECK(obj) EINA_FALSE; + + plug_img = elm_plug_image_object_get(obj); + if (!plug_img) return EINA_FALSE; + + ee = ecore_evas_object_ecore_evas_get(plug_img); + if (!ee) return EINA_FALSE; + ecore_evas_msg_parent_send(ee, msg_domain, msg_id, data, size); + return EINA_TRUE; +} diff --git a/src/lib/elm_plug.h b/src/lib/elm_plug.h index 4e91e06..31f95c7 100644 --- a/src/lib/elm_plug.h +++ b/src/lib/elm_plug.h @@ -16,6 +16,23 @@ */ /** + * @typedef Elm_Plug_Message + * + * Structure holding the message + * which elm plug received from ecore evas + * + */ +struct _Elm_Plug_Message +{ + int msg_domain; + int msg_id; + void *data; + int size; +}; + +typedef struct _Elm_Plug_Message Elm_Plug_Message; + +/** * Add a new plug image to the parent. * * @param parent The parent object @@ -56,5 +73,20 @@ EAPI Eina_Bool elm_plug_connect(Evas_Object *obj, const char *svcname, int EAPI Evas_Object *elm_plug_image_object_get(const Evas_Object *obj); /** + * Send message to plug widget's socket + * + * @param obj The plug object to send message + * @param msg_domain The domain of message + * @param msg_id The id of message + * @param data The data of message + * @param size The size of message data + * + * @warning Support for this depends on the underlying windowing system. + * @since 1.8.0 + * + */ +EAPI Eina_Bool elm_plug_msg_send(Evas_Object *obj, int msg_domain, int msg_id, void *data, int size); + +/** * @} */