X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Flib%2Felm_widget.c;h=24980f8dce65adcca5d1562e548a81e29eedc4e3;hb=d215ac8135d866b5486d3a91f3f9daedf4059a38;hp=4e6945adbb23003dbac703ecf2accd24c309a650;hpb=be0ada8ac91e977fe06dcf437b3e4d50f71629dc;p=framework%2Fuifw%2Felementary.git diff --git a/src/lib/elm_widget.c b/src/lib/elm_widget.c index 4e6945a..24980f8 100644 --- a/src/lib/elm_widget.c +++ b/src/lib/elm_widget.c @@ -13,6 +13,9 @@ static const char ELM_WIDGET_SMART_NAME[] = "elm_widget"; if (!sd) \ return +#define ELM_WIDGET_FOCUS_GET(obj) \ + ((_elm_access_read_mode_get()) ? (elm_widget_highlight_get(obj)) : \ + (elm_widget_focus_get(obj))) typedef struct _Elm_Event_Cb_Data Elm_Event_Cb_Data; typedef struct _Elm_Translate_String_Data Elm_Translate_String_Data; @@ -244,6 +247,7 @@ _elm_widget_sub_object_add_func(Evas_Object *obj, return EINA_FALSE; } sdc->parent_obj = obj; + sdc->orient_mode = sd->orient_mode; _elm_widget_top_win_focused_set(sobj, sd->top_win_focused); /* update child focusable-ness on self and parents, now that a @@ -415,41 +419,6 @@ _smart_add(Evas_Object *obj) } } -static Evas_Object * -_newest_focus_order_get(Evas_Object *obj, - unsigned int *newest_focus_order, - Eina_Bool can_focus_only) -{ - const Eina_List *l; - Evas_Object *child, *ret, *best; - - API_ENTRY return NULL; - - if (!evas_object_visible_get(obj) - || (elm_widget_disabled_get(obj)) - || (elm_widget_tree_unfocusable_get(obj))) - return NULL; - - best = NULL; - if (*newest_focus_order < sd->focus_order) - { - *newest_focus_order = sd->focus_order; - best = obj; - } - EINA_LIST_FOREACH(sd->subobjs, l, child) - { - ret = _newest_focus_order_get - (child, newest_focus_order, can_focus_only); - if (!ret) continue; - best = ret; - } - if (can_focus_only) - { - if ((!best) || (!elm_widget_can_focus_get(best))) - return NULL; - } - return best; -} static void _if_focused_revert(Evas_Object *obj, @@ -467,8 +436,8 @@ _if_focused_revert(Evas_Object *obj, top = elm_widget_top_get(sd->parent_obj); if (top) { - newest = _newest_focus_order_get - (top, &newest_focus_order, can_focus_only); + newest = elm_widget_newest_focus_order_get + (top, &newest_focus_order, can_focus_only); if (newest) { elm_object_focus_set(newest, EINA_FALSE); @@ -1831,7 +1800,15 @@ elm_widget_focus_cycle(Evas_Object *obj, return; elm_widget_focus_next_get(obj, dir, &target); if (target) - elm_widget_focus_steal(target); + { + /* access */ + if (_elm_config->access_mode && _elm_access_read_mode_get()) + { + _elm_access_highlight_set(target); + _elm_widget_focus_region_show(target); + } + else elm_widget_focus_steal(target); + } } /** @@ -2354,14 +2331,65 @@ elm_widget_focus_next_get(const Evas_Object *obj, /* Try use hook */ if (_elm_widget_focus_chain_manager_is(obj)) - return sd->api->focus_next(obj, dir, next); + { + Eina_Bool ret; + ret = sd->api->focus_next(obj, dir, next); + if (!ret && elm_widget_focus_get(obj)) + { + Evas_Object *o = NULL; + if (dir == ELM_FOCUS_PREVIOUS) + o = sd->focus_previous; + else if (dir == ELM_FOCUS_NEXT) + o = sd->focus_next; + else if (dir == ELM_FOCUS_UP) + o = sd->focus_up; + else if (dir == ELM_FOCUS_DOWN) + o = sd->focus_down; + else if (dir == ELM_FOCUS_RIGHT) + o = sd->focus_right; + else if (dir == ELM_FOCUS_LEFT) + o = sd->focus_left; + + if (o) + { + *next = o; + return EINA_TRUE; + } + } + else + return ret; + } if (!elm_widget_can_focus_get(obj)) return EINA_FALSE; + /* focusable object but does not have access info */ + if (_elm_config->access_mode) + { + if (!_elm_access_object_get(obj)) return EINA_FALSE; + } + + if (elm_widget_focus_get(obj)) + { + if (dir == ELM_FOCUS_PREVIOUS) + *next = sd->focus_previous; + else if (dir == ELM_FOCUS_NEXT) + *next = sd->focus_next; + else if (dir == ELM_FOCUS_UP) + *next = sd->focus_up; + else if (dir == ELM_FOCUS_DOWN) + *next = sd->focus_down; + else if (dir == ELM_FOCUS_RIGHT) + *next = sd->focus_right; + else if (dir == ELM_FOCUS_LEFT) + *next = sd->focus_left; + + if (*next) + return EINA_TRUE; + } /* Return */ *next = (Evas_Object *)obj; - return !elm_widget_focus_get(obj); + return !ELM_WIDGET_FOCUS_GET(obj); } /** @@ -2391,6 +2419,7 @@ elm_widget_focus_list_next_get(const Evas_Object *obj, Evas_Object **next) { Eina_List *(*list_next)(const Eina_List *list) = NULL; + Evas_Object *focused_object = NULL; if (!next) return EINA_FALSE; @@ -2402,13 +2431,51 @@ elm_widget_focus_list_next_get(const Evas_Object *obj, if (!items) return EINA_FALSE; + /* When Up, Down, Right, or Left, try direction_get first. */ + focused_object = elm_widget_focused_object_get(obj); + if (focused_object) + { + if((dir == ELM_FOCUS_UP) + || (dir == ELM_FOCUS_DOWN) + || (dir == ELM_FOCUS_RIGHT) + || (dir == ELM_FOCUS_LEFT)) + { + *next = elm_widget_focus_next_object_get(focused_object, dir); + if (*next) + return EINA_TRUE; + else + { + Evas_Object *n; + double degree; + double weight; + + if (dir == ELM_FOCUS_UP) degree = 0.0; + else if (dir == ELM_FOCUS_DOWN) degree = 180.0; + else if (dir == ELM_FOCUS_RIGHT) degree = 90.0; + else if (dir == ELM_FOCUS_LEFT) degree = 270.0; + + if (elm_widget_focus_list_direction_get(obj, focused_object, + items, list_data_get, + degree, &n, &weight)) + { + *next = n; + return EINA_TRUE; + } + } + } + } + /* Direction */ if (dir == ELM_FOCUS_PREVIOUS) { items = eina_list_last(items); list_next = eina_list_prev; } - else if (dir == ELM_FOCUS_NEXT) + else if ((dir == ELM_FOCUS_NEXT) + || (dir == ELM_FOCUS_UP) + || (dir == ELM_FOCUS_DOWN) + || (dir == ELM_FOCUS_RIGHT) + || (dir == ELM_FOCUS_LEFT)) list_next = eina_list_next; else return EINA_FALSE; @@ -2416,12 +2483,12 @@ elm_widget_focus_list_next_get(const Evas_Object *obj, const Eina_List *l = items; /* Recovery last focused sub item */ - if (elm_widget_focus_get(obj)) + if (ELM_WIDGET_FOCUS_GET(obj)) { for (; l; l = list_next(l)) { Evas_Object *cur = list_data_get(l); - if (elm_widget_focus_get(cur)) break; + if (ELM_WIDGET_FOCUS_GET(cur)) break; } /* Focused object, but no focused sub item */ @@ -2447,6 +2514,17 @@ elm_widget_focus_list_next_get(const Evas_Object *obj, *next = tmp; return EINA_TRUE; } + else if ((dir == ELM_FOCUS_UP) + || (dir == ELM_FOCUS_DOWN) + || (dir == ELM_FOCUS_RIGHT) + || (dir == ELM_FOCUS_LEFT)) + { + if (tmp && elm_widget_focus_get(cur)) + { + *next = tmp; + return EINA_FALSE; + } + } else if ((tmp) && (!to_focus)) to_focus = tmp; } @@ -2475,6 +2553,100 @@ elm_widget_focus_list_next_get(const Evas_Object *obj, return EINA_FALSE; } + +/** + * @internal + * + * Get next object which was set with specific focus direction. + * + * Get next object which was set by elm_widget_focus_next_object_set + * with specific focus directioin. + * + * @param obj The widget + * @param dir Direction of focus + * @return Widget which was registered with sepecific focus direction. + * + * @ingroup Widget + */ +EAPI Evas_Object * +elm_widget_focus_next_object_get(const Evas_Object *obj, Elm_Focus_Direction dir) +{ + API_ENTRY return NULL; + + if (dir == ELM_FOCUS_PREVIOUS) + return sd->focus_previous; + else if (dir == ELM_FOCUS_NEXT) + return sd->focus_next; + else if (dir == ELM_FOCUS_UP) + return sd->focus_up; + else if (dir == ELM_FOCUS_DOWN) + return sd->focus_down; + else if (dir == ELM_FOCUS_RIGHT) + return sd->focus_right; + else if (dir == ELM_FOCUS_LEFT) + return sd->focus_left; + + return NULL; +} + +/** + * @internal + * + * Set next object with specific focus direction. + * + * When a widget is set with specific focus direction, this widget will be + * the first candidate when finding the next focus object. + * Focus next object can be registered with six directions that are previous, + * next, up, down, right, and left. + * + * @param obj The widget + * @param next Next focus object + * @param dir Direction of focus + * + * @ingroup Widget + */ +EAPI void +elm_widget_focus_next_object_set(Evas_Object *obj, Evas_Object *next, Elm_Focus_Direction dir) +{ + API_ENTRY return; + + if (dir == ELM_FOCUS_PREVIOUS) + sd->focus_previous = next; + else if (dir == ELM_FOCUS_NEXT) + sd->focus_next = next; + else if (dir == ELM_FOCUS_UP) + sd->focus_up = next; + else if (dir == ELM_FOCUS_DOWN) + sd->focus_down = next; + else if (dir == ELM_FOCUS_RIGHT) + sd->focus_right = next; + else if (dir == ELM_FOCUS_LEFT) + sd->focus_left = next; +} + + +EAPI Eina_Bool +elm_widget_highlight_get(const Evas_Object *obj) +{ + API_ENTRY return EINA_FALSE; + return sd->highlighted; +} + +EAPI void +elm_widget_parent_highlight_set(Evas_Object *obj, + Eina_Bool highlighted) +{ + API_ENTRY return; + + highlighted = !!highlighted; + + Evas_Object *o = elm_widget_parent_get(obj); + + if (o) elm_widget_parent_highlight_set(o, highlighted); + + sd->highlighted = highlighted; +} + EAPI void elm_widget_signal_emit(Evas_Object *obj, const char *emission, @@ -2616,6 +2788,10 @@ elm_widget_focused_object_clear(Evas_Object *obj) if (!sd->api) return; if (!sd->focused) return; + + // FIXME: evas_object_ref/unref is temporary code to fix logical issue. + // After Eo is applied to elementary, remove these. + evas_object_ref(obj); if (sd->resize_obj && elm_widget_focus_get(sd->resize_obj)) elm_widget_focused_object_clear(sd->resize_obj); else @@ -2633,6 +2809,7 @@ elm_widget_focused_object_clear(Evas_Object *obj) } sd->focused = EINA_FALSE; sd->api->on_focus(obj); + evas_object_unref(obj); } EAPI void @@ -2695,7 +2872,7 @@ elm_widget_focus_restore(Evas_Object *obj) unsigned int newest_focus_order = 0; API_ENTRY return; - newest = _newest_focus_order_get(obj, &newest_focus_order, EINA_TRUE); + newest = elm_widget_newest_focus_order_get(obj, &newest_focus_order, EINA_TRUE); if (newest) { elm_object_focus_set(newest, EINA_FALSE); @@ -3070,35 +3247,32 @@ elm_widget_text_part_get(const Evas_Object *obj, return NULL; } -EAPI void -elm_widget_domain_translatable_text_part_set(Evas_Object *obj, - const char *part, - const char *domain, - const char *label) +static Eina_Bool +_translatable_part_text_set(Eina_List **translate_strings, const char *part, const char *domain, const char *label) { const char *str; - Eina_List *l; + Eina_List *t, *l; Elm_Translate_String_Data *ts = NULL; - API_ENTRY return; + t = *translate_strings; str = eina_stringshare_add(part); - EINA_LIST_FOREACH(sd->translate_strings, l, ts) - if (ts->id == str) - break; - else - ts = NULL; + EINA_LIST_FOREACH(t, l, ts) + { + if (ts->id == str) break; + else ts = NULL; + } if (!ts && !label) eina_stringshare_del(str); else if (!ts) { ts = malloc(sizeof(Elm_Translate_String_Data)); - if (!ts) return; + if (!ts) return EINA_FALSE; ts->id = str; ts->domain = eina_stringshare_add(domain); ts->string = eina_stringshare_add(label); - sd->translate_strings = eina_list_append(sd->translate_strings, ts); + t = eina_list_append(t, ts); } else { @@ -3109,8 +3283,7 @@ elm_widget_domain_translatable_text_part_set(Evas_Object *obj, } else { - sd->translate_strings = eina_list_remove_list( - sd->translate_strings, l); + t = eina_list_remove_list(t, l); eina_stringshare_del(ts->id); eina_stringshare_del(ts->domain); eina_stringshare_del(ts->string); @@ -3119,6 +3292,20 @@ elm_widget_domain_translatable_text_part_set(Evas_Object *obj, eina_stringshare_del(str); } + *translate_strings = t; + return EINA_TRUE; +} + +EAPI void +elm_widget_domain_translatable_part_text_set(Evas_Object *obj, + const char *part, + const char *domain, + const char *label) +{ + API_ENTRY return; + + if (!_translatable_part_text_set(&sd->translate_strings, part, domain, + label)) return; #ifdef HAVE_GETTEXT if (label && label[0]) label = dgettext(domain, label); @@ -3126,26 +3313,33 @@ elm_widget_domain_translatable_text_part_set(Evas_Object *obj, elm_widget_text_part_set(obj, part, label); } -EAPI const char * -elm_widget_translatable_text_part_get(const Evas_Object *obj, - const char *part) +static const char * +_translatable_part_text_get(Eina_List *translate_strings, const char *part) { - const char *str, *ret = NULL; - Eina_List *l; Elm_Translate_String_Data *ts; - API_ENTRY return NULL; + const char*ret = NULL, *str; + Eina_List *l; str = eina_stringshare_add(part); - EINA_LIST_FOREACH(sd->translate_strings, l, ts) + EINA_LIST_FOREACH(translate_strings, l, ts) if (ts->id == str) { ret = ts->string; break; } eina_stringshare_del(str); + return ret; } +EAPI const char * +elm_widget_translatable_part_text_get(const Evas_Object *obj, + const char *part) +{ + API_ENTRY return NULL; + return _translatable_part_text_get(sd->translate_strings, part); +} + EAPI void elm_widget_translate(Evas_Object *obj) { @@ -3353,7 +3547,19 @@ elm_widget_theme_object_set(Evas_Object *obj, const char *wstyle) { API_ENTRY return EINA_FALSE; - return _elm_theme_object_set(obj, edj, wname, welement, wstyle); + char buf[128]; + + if (!_elm_theme_object_set(obj, edj, wname, welement, wstyle)) + return EINA_FALSE; + + if (sd->orient_mode != -1) + { + + snprintf(buf, sizeof(buf), "elm,state,orient,%d", sd->orient_mode); + elm_widget_signal_emit(obj, buf, "elm"); + + } + return EINA_TRUE; } EAPI Eina_Bool @@ -3458,6 +3664,62 @@ elm_widget_name_find(const Evas_Object *obj, return _widget_name_find(obj, name, recurse); } +EAPI void +elm_widget_orientation_mode_disabled_set(Evas_Object *obj, Eina_Bool disabled) +{ + int orient_mode = -1; + + API_ENTRY return; + + if (disabled && (sd->orient_mode == -1)) return; + if (!disabled && (sd->orient_mode != -1)) return; + + if (!disabled) + { + //Get current orient mode from it's parent otherwise, 0. + sd->orient_mode = 0; + ELM_WIDGET_DATA_GET(sd->parent_obj, sd_parent); + if (!sd_parent) orient_mode = 0; + else orient_mode = sd_parent->orient_mode; + } + elm_widget_orientation_set(obj, orient_mode); +} + +EAPI Eina_Bool +elm_widget_orientation_mode_disabled_get(const Evas_Object *obj) +{ + Eina_Bool ret; + + API_ENTRY return EINA_FALSE; + + if (sd->orient_mode == -1) ret = EINA_TRUE; + else ret = EINA_FALSE; + return ret; +} + +EAPI void +elm_widget_orientation_set(Evas_Object *obj, int rotation) +{ + Evas_Object *child; + Eina_List *l; + + API_ENTRY return; + + if ((sd->orient_mode == rotation) || (sd->orient_mode == -1)) return; + + sd->orient_mode = rotation; + + EINA_LIST_FOREACH (sd->subobjs, l, child) + elm_widget_orientation_set(child, rotation); + + if (rotation != -1) + { + char buf[128]; + snprintf(buf, sizeof(buf), "elm,state,orient,%d", sd->orient_mode); + elm_widget_signal_emit(obj, buf, "elm"); + } +} + /** * @internal * @@ -3553,6 +3815,42 @@ elm_widget_focus_order_get(const Evas_Object *obj) return sd->focus_order; } +EAPI Evas_Object * +elm_widget_newest_focus_order_get(const Evas_Object *obj, + unsigned int *newest_focus_order, + Eina_Bool can_focus_only) +{ + const Eina_List *l; + Evas_Object *child, *ret, *best; + + API_ENTRY return NULL; + + if (!evas_object_visible_get(obj) + || (elm_widget_disabled_get(obj)) + || (elm_widget_tree_unfocusable_get(obj))) + return NULL; + + best = NULL; + if (*newest_focus_order < sd->focus_order) + { + *newest_focus_order = sd->focus_order; + best = (Evas_Object *)obj; + } + EINA_LIST_FOREACH(sd->subobjs, l, child) + { + ret = elm_widget_newest_focus_order_get + (child, newest_focus_order, can_focus_only); + if (!ret) continue; + best = ret; + } + if (can_focus_only) + { + if ((!best) || (!elm_widget_can_focus_get(best))) + return NULL; + } + return best; +} + EAPI void elm_widget_activate(Evas_Object *obj, Elm_Activate act) { @@ -3640,6 +3938,19 @@ elm_widget_display_mode_set(Evas_Object *obj, Evas_Display_Mode dispmode) } +// temporary code. should be removed after eo is applied. +EAPI void +_elm_widget_orient_signal_emit(Evas_Object *obj) +{ + ELM_WIDGET_DATA_GET(obj, sd); + char buf[128]; + if (sd->orient_mode > 0) + { + snprintf(buf, sizeof(buf), "elm,state,orient,%d", sd->orient_mode); + elm_widget_signal_emit(obj, buf, "elm"); + } +} + /** * @internal * @@ -3682,6 +3993,9 @@ _elm_widget_item_new(Evas_Object *widget, EAPI void _elm_widget_item_free(Elm_Widget_Item *item) { + Elm_Translate_String_Data *ts; + Elm_Widget_Item_Signal_Data *wisd; + ELM_WIDGET_ITEM_CHECK_OR_RETURN(item); if (item->del_func) @@ -3693,6 +4007,21 @@ _elm_widget_item_free(Elm_Widget_Item *item) if (item->access_info) eina_stringshare_del(item->access_info); + EINA_LIST_FREE(item->signals, wisd) + { + eina_stringshare_del(wisd->emission); + eina_stringshare_del(wisd->source); + free(wisd); + } + + EINA_LIST_FREE(item->translate_strings, ts) + { + eina_stringshare_del(ts->id); + eina_stringshare_del(ts->domain); + eina_stringshare_del(ts->string); + free(ts); + } + EINA_MAGIC_SET(item, EINA_MAGIC_NONE); free(item); } @@ -3724,8 +4053,12 @@ _elm_widget_item_del(Elm_Widget_Item *item) //Widget item delete callback if (item->del_pre_func) - if (item->del_pre_func((Elm_Object_Item *)item)) - _elm_widget_item_free(item); + { + if (item->del_pre_func((Elm_Object_Item *)item)) + _elm_widget_item_free(item); + } + else + _elm_widget_item_free(item); } /** @@ -3887,6 +4220,31 @@ _elm_widget_item_disable_hook_set(Elm_Widget_Item *item, item->disable_func = func; } +EAPI void +_elm_widget_item_domain_translatable_part_text_set(Elm_Widget_Item *item, + const char *part, + const char *domain, + const char *label) +{ + ELM_WIDGET_ITEM_CHECK_OR_RETURN(item); + + if (!_translatable_part_text_set(&item->translate_strings, part, domain, + label)) return; +#ifdef HAVE_GETTEXT + if (label && label[0]) + label = dgettext(domain, label); +#endif + _elm_widget_item_part_text_set(item, part, label); +} + +EAPI const char * +_elm_widget_item_translatable_part_text_get(const Elm_Widget_Item *item, + const char *part) +{ + ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL); + return _translatable_part_text_get(item->translate_strings, part); +} + typedef struct _Elm_Widget_Item_Tooltip Elm_Widget_Item_Tooltip; struct _Elm_Widget_Item_Tooltip @@ -4395,6 +4753,88 @@ _elm_widget_item_signal_emit_hook_set(Elm_Widget_Item *item, item->signal_emit_func = func; } + +static void +_elm_widget_item_signal_cb(void *data, Evas_Object *obj __UNUSED__, const char *emission, + const char *source) +{ + Elm_Widget_Item_Signal_Data *wisd = data; + wisd->func(wisd->data, wisd->item, emission, source); +} + +EAPI void +_elm_widget_item_signal_callback_add(Elm_Widget_Item *item, + const char *emission, + const char *source, + Elm_Widget_Item_Signal_Cb func, + void *data) +{ + ELM_WIDGET_ITEM_CHECK_OR_RETURN(item); + EINA_SAFETY_ON_NULL_RETURN(func); + + Elm_Widget_Item_Signal_Data *wisd; + + wisd = malloc(sizeof(Elm_Widget_Item_Signal_Data)); + if (!wisd) return; + + wisd->item = item; + wisd->func = func; + wisd->data = data; + wisd->emission = eina_stringshare_add(emission); + wisd->source = eina_stringshare_add(source); + + if (_elm_widget_is(item->view)) + elm_object_signal_callback_add(item->view, emission, source, _elm_widget_item_signal_cb, wisd); + else if (!strcmp(evas_object_type_get(item->view), "edje")) + edje_object_signal_callback_add(item->view, emission, source, _elm_widget_item_signal_cb, wisd); + else + { + WRN("The %s widget item doesn't support signal callback add!", + evas_object_type_get(item->widget)); + free(wisd); + return; + } + + item->signals = eina_list_append(item->signals, wisd); +} + +EAPI void * +_elm_widget_item_signal_callback_del(Elm_Widget_Item *item, + const char *emission, + const char *source, + Elm_Widget_Item_Signal_Cb func) +{ + ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL); + EINA_SAFETY_ON_NULL_RETURN_VAL(func, NULL); + + Elm_Widget_Item_Signal_Data *wisd; + Eina_List *l; + void *data = NULL; + + EINA_LIST_FOREACH(item->signals, l, wisd) + { + if ((wisd->func == func) && !strcmp(wisd->emission, emission) && + !strcmp(wisd->source, source)) + { + item->signals = eina_list_remove_list(item->signals, l); + eina_stringshare_del(wisd->emission); + eina_stringshare_del(wisd->source); + data = wisd->data; + + if (_elm_widget_is(item->view)) + elm_object_signal_callback_del(item->view, emission, source, + _elm_widget_item_signal_cb); + else if (!strcmp(evas_object_type_get(item->view), "edje")) + edje_object_signal_callback_del_full(item->view, emission, + source, + _elm_widget_item_signal_cb, + data); + } + } + + return data; +} + EAPI void _elm_widget_item_access_info_set(Elm_Widget_Item *item, const char *txt)