elm_widget_disabled_internal(Eo *obj, Eina_Bool disabled);
static void
_on_sub_obj_del(void *data, const Efl_Event *event);
-static void
-_on_sub_obj_hide(void *data, const Efl_Event *event);
static void _propagate_event(void *data, const Efl_Event *eo_event);
static void _elm_widget_focus_tree_unfocusable_handle(Eo *obj);
EFL_CALLBACKS_ARRAY_DEFINE(elm_widget_subitems_callbacks,
- { EFL_EVENT_DEL, _on_sub_obj_del },
- { EFL_GFX_EVENT_HIDE, _on_sub_obj_hide });
+ { EFL_EVENT_DEL, _on_sub_obj_del });
EFL_CALLBACKS_ARRAY_DEFINE(efl_subitems_callbacks,
{ EFL_EVENT_DEL, _on_sub_obj_del });
EFL_CALLBACKS_ARRAY_DEFINE(focus_callbacks,
}
static void
-_on_sub_obj_hide(void *data EINA_UNUSED, const Efl_Event *event)
-{
- elm_obj_widget_focus_hide_handle(event->object);
-}
-
-static void
_on_sub_obj_del(void *data, const Efl_Event *event)
{
ELM_WIDGET_DATA_GET_OR_RETURN(data, sd);
_obj_mouse_in, obj);
}
-static void
-_if_focused_revert(Evas_Object *obj,
- Eina_Bool can_focus_only)
-{
- Evas_Object *top;
- Evas_Object *newest = NULL;
- unsigned int newest_focus_order = 0;
-
- INTERNAL_ENTRY;
-
- if (!sd->focused) return;
- if (!sd->parent_obj) return;
-
- top = elm_widget_top_get(sd->parent_obj);
- if (top)
- {
- newest = elm_widget_newest_focus_order_get
- (top, &newest_focus_order, can_focus_only);
- if (newest)
- {
- if (newest == top)
- {
- ELM_WIDGET_DATA_GET(newest, sd2);
- if (!sd2) return;
-
- if (!_is_focused(newest))
- elm_obj_widget_focus_steal(newest, NULL);
- else
- {
- if (sd2->resize_obj && _is_focused(sd2->resize_obj))
- elm_obj_widget_focused_object_clear(sd2->resize_obj);
- else
- {
- const Eina_List *l;
- Evas_Object *child;
- EINA_LIST_FOREACH(sd2->subobjs, l, child)
- {
- if (!_elm_widget_is(child)) continue;
- if (_is_focused(child))
- {
- elm_obj_widget_focused_object_clear(child);
- break;
- }
- }
- }
- }
- evas_object_focus_set(newest, EINA_TRUE);
- }
- else
- {
- elm_object_focus_set(newest, EINA_FALSE);
- elm_object_focus_set(newest, EINA_TRUE);
- }
- }
- }
-}
-
EOLIAN static void
_elm_widget_efl_canvas_group_group_del(Eo *obj, Elm_Widget_Smart_Data *sd)
{
eina_stringshare_del(sd->style);
if (sd->theme) elm_theme_free(sd->theme);
- _if_focused_revert(obj, EINA_TRUE);
- elm_obj_widget_focus_custom_chain_unset(obj);
eina_stringshare_del(sd->access_info);
eina_stringshare_del(sd->accessible_name);
evas_object_smart_data_set(obj, NULL);
}
// internal funcs
-/**
- * @internal
- *
- * Check if the widget has its own focus next function.
- *
- * @param obj The widget.
- * @return focus next function is implemented/unimplemented.
- * (@c EINA_TRUE = implemented/@c EINA_FALSE = unimplemented.)
- */
-static inline Eina_Bool
-_elm_widget_focus_chain_manager_is(const Evas_Object *obj)
-{
- ELM_WIDGET_CHECK(obj) EINA_FALSE;
-
- Eina_Bool manager_is = EINA_FALSE;
- manager_is = elm_obj_widget_focus_next_manager_is((Eo *)obj);
- return manager_is;
-}
-
-static inline Eina_Bool
-_internal_elm_widget_focus_direction_manager_is(const Evas_Object *obj)
-{
- ELM_WIDGET_CHECK(obj) EINA_FALSE;
-
- Eina_Bool manager_is = EINA_FALSE;
- manager_is = elm_obj_widget_focus_direction_manager_is((Eo *)obj);
- return manager_is;
-}
-
static void
_propagate_x_drag_lock(Evas_Object *obj,
int dir)
}
}
-static void
-_parent_focus(Evas_Object *obj, Elm_Object_Item *item)
-{
- API_ENTRY return;
-
- if (sd->focused) return;
-
- Evas_Object *o = elm_widget_parent_get(obj);
- sd->focus_order_on_calc = EINA_TRUE;
-
- if (o) _parent_focus(o, item);
-
- if (!sd->focus_order_on_calc)
- return; /* we don't want to override it if by means of any of the
- callbacks below one gets to calculate our order
- first. */
-
- focus_order++;
- sd->focus_order = focus_order;
- sd->focused = EINA_TRUE;
-
- if (sd->top_win_focused)
- elm_obj_widget_on_focus_update(obj, item);
- sd->focus_order_on_calc = EINA_FALSE;
-
- if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
- _elm_access_highlight_set(obj);
-}
-
-static void
-_elm_object_focus_chain_del_cb(void *data,
- Evas *e EINA_UNUSED,
- Evas_Object *obj,
- void *event_info EINA_UNUSED)
-{
- ELM_WIDGET_DATA_GET(data, sd);
-
- sd->focus_chain = eina_list_remove(sd->focus_chain, obj);
-}
-
EOLIAN static void
_elm_widget_widget_parent_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED, Evas_Object *parent EINA_UNUSED)
{
{
if (!sdc->disabled && (elm_widget_disabled_get(obj)))
{
- elm_obj_widget_focus_disabled_handle(sobj);
elm_obj_widget_on_disabled_update(sobj, EINA_TRUE);
}
}
}
EOLIAN static Evas_Object*
-_elm_widget_focused_object_get(Eo *obj, Elm_Widget_Smart_Data *sd)
-{
- const Evas_Object *subobj;
- const Eina_List *l;
-
- if (!sd->focused || !sd->top_win_focused) return NULL;
- EINA_LIST_FOREACH(sd->subobjs, l, subobj)
- {
- Evas_Object *fobj;
- if (!_elm_widget_is(subobj)) continue;
- fobj = elm_obj_widget_focused_object_get(subobj);
- if (fobj) return fobj;
- }
- return (Evas_Object *)obj;
-}
-
-EOLIAN static Evas_Object*
_elm_widget_widget_top_get(Eo *obj, Elm_Widget_Smart_Data *sd)
{
if (sd->parent_obj)
}
}
-/**
- * @internal
- *
- * Set custom focus chain.
- *
- * This function i set one new and overwrite any previous custom focus chain
- * with the list of objects. The previous list will be deleted and this list
- * will be managed. After setted, don't modity it.
- *
- * @note On focus cycle, only will be evaluated children of this container.
- *
- * @param obj The container widget
- * @param objs Chain of objects to pass focus
- * @ingroup Widget
- */
-EOLIAN static void
-_elm_widget_focus_custom_chain_set(Eo *obj, Elm_Widget_Smart_Data *sd, Eina_List *objs)
-{
- if (!_elm_widget_focus_chain_manager_is(obj)) return;
-
- elm_obj_widget_focus_custom_chain_unset(obj);
-
- Eina_List *l;
- Evas_Object *o;
-
- EINA_LIST_FOREACH(objs, l, o)
- {
- evas_object_event_callback_add(o, EVAS_CALLBACK_DEL,
- _elm_object_focus_chain_del_cb, obj);
- }
-
- sd->focus_chain = objs;
-}
-
-/**
- * @internal
- *
- * Get custom focus chain
- *
- * @param obj The container widget
- * @ingroup Widget
- */
-EOLIAN static const Eina_List*
-_elm_widget_focus_custom_chain_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
-{
- return (const Eina_List *)sd->focus_chain;
-}
-
-/**
- * @internal
- *
- * Unset custom focus chain
- *
- * @param obj The container widget
- * @ingroup Widget
- */
-EOLIAN static void
-_elm_widget_focus_custom_chain_unset(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
-{
- Eina_List *l, *l_next;
- Evas_Object *o;
-
- EINA_LIST_FOREACH_SAFE(sd->focus_chain, l, l_next, o)
- {
- evas_object_event_callback_del_full(o, EVAS_CALLBACK_DEL,
- _elm_object_focus_chain_del_cb, obj);
- sd->focus_chain = eina_list_remove_list(sd->focus_chain, l);
- }
-}
-
-/**
- * @internal
- *
- * Append object to custom focus chain.
- *
- * @note If relative_child equal to NULL or not in custom chain, the object
- * will be added in end.
- *
- * @note On focus cycle, only will be evaluated children of this container.
- *
- * @param obj The container widget
- * @param child The child to be added in custom chain
- * @param relative_child The relative object to position the child
- * @ingroup Widget
- */
-EOLIAN static void
-_elm_widget_focus_custom_chain_append(Eo *obj, Elm_Widget_Smart_Data *sd, Evas_Object *child, Evas_Object *relative_child)
-{
- EINA_SAFETY_ON_NULL_RETURN(child);
-
- if (!_elm_widget_focus_chain_manager_is(obj)) return;
-
- evas_object_event_callback_add(child, EVAS_CALLBACK_DEL,
- _elm_object_focus_chain_del_cb, obj);
-
- if (!relative_child)
- sd->focus_chain = eina_list_append(sd->focus_chain, child);
- else
- sd->focus_chain = eina_list_append_relative(sd->focus_chain,
- child, relative_child);
-}
-
-/**
- * @internal
- *
- * Prepend object to custom focus chain.
- *
- * @note If relative_child equal to NULL or not in custom chain, the object
- * will be added in begin.
- *
- * @note On focus cycle, only will be evaluated children of this container.
- *
- * @param obj The container widget
- * @param child The child to be added in custom chain
- * @param relative_child The relative object to position the child
- * @ingroup Widget
- */
-EOLIAN static void
-_elm_widget_focus_custom_chain_prepend(Eo *obj, Elm_Widget_Smart_Data *sd, Evas_Object *child, Evas_Object *relative_child)
-{
- EINA_SAFETY_ON_NULL_RETURN(child);
-
- if (!_elm_widget_focus_chain_manager_is(obj)) return;
-
- evas_object_event_callback_add(child, EVAS_CALLBACK_DEL,
- _elm_object_focus_chain_del_cb, obj);
-
- if (!relative_child)
- sd->focus_chain = eina_list_prepend(sd->focus_chain, child);
- else
- sd->focus_chain = eina_list_prepend_relative(sd->focus_chain,
- child, relative_child);
-}
-
-/**
- * @internal
- *
- * Give focus to next object in object tree.
- *
- * Give focus to next object in focus chain of one object sub-tree.
- * If the last object of chain already have focus, the focus will go to the
- * first object of chain.
- *
- * @param obj The widget root of sub-tree
- * @param dir Direction to cycle the focus
- *
- * @ingroup Widget
- */
-EOLIAN static void
-_elm_widget_focus_cycle(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED, Elm_Focus_Direction dir)
-{
- Evas_Object *target = NULL;
- Elm_Object_Item *target_item = NULL;
- if (!_elm_widget_is(obj))
- return;
- elm_obj_widget_focus_next_get(obj, dir, &target, &target_item);
- if (target)
- {
- /* access */
- if (_elm_config->access_mode)
- {
- /* highlight cycle does not steal a focus, only after window gets
- the ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_ACTIVATE message,
- target will steal focus, or focus its own job. */
- if (!_elm_access_auto_highlight_get())
- elm_obj_widget_focus_steal(target, target_item);
-
- _elm_access_highlight_set(target);
- elm_widget_focus_region_show(target);
- }
- else elm_obj_widget_focus_steal(target, target_item);
- }
-}
-
-/**
- * @internal
- *
- * Give focus to near object(in object tree) in one direction.
- *
- * Give focus to near object(in object tree) in direction of current
- * focused object. If none focusable object in given direction or
- * none focused object in object tree, the focus will not change.
- *
- * @param obj The reference widget
- * @param degree Degree changes clockwise. i.e. 0-degree: Up,
- * 90-degree: Right, 180-degree: Down, and 270-degree: Left
- * @return EINA_TRUE if focus is moved.
- *
- * @ingroup Widget
- */
-EOLIAN static Eina_Bool
-_elm_widget_focus_direction_go(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED, double degree)
-{
- Evas_Object *target = NULL;
- Elm_Object_Item *target_item = NULL;
- Evas_Object *current_focused = NULL;
- double weight = 0.0;
-
- if (!_elm_widget_is(obj)) return EINA_FALSE;
- if (!_is_focused(obj)) return EINA_FALSE;
-
- current_focused = elm_obj_widget_focused_object_get(obj);
-
- if (elm_obj_widget_focus_direction_get
- (obj, current_focused, degree, &target, &target_item, &weight))
- {
- elm_obj_widget_focus_steal(target, NULL);
- return EINA_TRUE;
- }
-
- return EINA_FALSE;
-}
-
double
_elm_widget_focus_direction_weight_get(const Evas_Object *obj1,
const Evas_Object *obj2,
weight = (xx2 * xx2) + ((yy1 - yyy2) * (yy1 - yyy2));
else weight = (yy1 - yyy2) * (yy1 - yyy2);
}
- else
- {
- int j = 0, k = 0;
- double sx[4] = {0.0, 0.0, 0.0, 0.0}, sy[4] = {0.0, 0.0, 0.0, 0.0};
- double t_weight[4] = {-1.0, -1.0, -1.0, -1.0};
- if ((_R(g * x2) >= _R(yy2)) && (_R(g * x2) <= _R(yyy2)))
- {
- sx[j] = x2;
- sy[j] = g * x2;
- t_weight[j++] = ((ax - x2) * (ax - x2)) +
- ((ay - (g * x2)) * (ay - (g * x2)));
- }
- if ((_R(g * xx2) >= _R(yy2)) && (_R(g * xx2) <= _R(yyy2)))
- {
- sx[j] = xx2;
- sy[j] = g * xx2;
- t_weight[j++] = ((ax - xx2) * (ax - xx2)) +
- ((ay - (g * xx2)) * (ay - (g * xx2)));
- }
- if ((_R((1.0 / g) * yy2) >= _R(x2)) && (_R((1.0 / g) * yy2) <= _R(xx2)))
- {
- sx[j] = (1.0 / g) * yy2;
- sy[j] = yy2;
- t_weight[j++] =
- ((ax - ((1.0 / g) * yy2)) * (ax - ((1.0 / g) * yy2))) +
- ((ay - yy2) * (ay - yy2));
- }
- if ((_R((1.0 / g) * yyy2) >= _R(x2)) && (_R((1.0 / g) * yyy2)
- <= _R(xx2)))
- {
- sx[j] = (1.0 / g) * yyy2;
- sy[j] = yyy2;
- t_weight[j++] =
- ((ax - ((1.0 / g) * yyy2)) * (ax - ((1.0 / g) * yyy2))) +
- ((ay - yyy2) * (ay - yyy2));
- }
-
- if ((j > 2) || ((j == 2) && ((_R(sx[0]) != _R(sx[1])) ||
- (_R(sy[0]) != _R(sy[1])))))
- {
- for (; k < j; k++)
- {
- if (_R(t_weight[k]) == 0) return -1.0;
- if ((1 / weight) < (1 / t_weight[k])) weight = t_weight[k];
- }
- }
- else
- {
- for (; k < i; k++)
- {
- double ccx, ccy, t1_weight, x_diff, y_diff;
- ccx = ((1.0 / g) * rx[k] + ry[k]) / (g + (1.0 / g));
- ccy = g * ccx;
- x_diff = rx[k] - ccx;
- if (x_diff < 0) x_diff *= -1.0;
- y_diff = ry[k] - ccy;
- if (y_diff < 0) y_diff *= -1.0;
- t1_weight =
- (((ax - ccx) * (ax - ccx)) + ((ay - ccy) * (ay - ccy))) +
- ((x_diff * x_diff * x_diff) + (y_diff * y_diff * y_diff));
- if ((_R(t1_weight) != 0) && ((1 / weight) < (1 / t1_weight)))
- weight = t1_weight;
- }
- }
- }
- /* Return the current object's weight. */
- if (weight == -1.0) return 0.0;
- if (_R(weight) == 0) return -1.0;
-
-#undef _R
-
- return 1.0 / weight;
-}
-
-/**
- * @internal
- *
- * Get near object in one direction of base object.
- *
- * Get near object(in the object sub-tree) in one direction of
- * base object. Return the near object by reference.
- * By initializing weight, you can filter objects locating far
- * from base object. If object is in the specific direction,
- * weight is (1/(distance^2)). If object is not exactly in one
- * direction, some penalty will be added.
- *
- * @param obj The widget root of sub-tree
- * @param base The base object of the direction
- * @param degree Degree changes clockwise. i.e. 0-degree: Up,
- * 90-degree: Right, 180-degree: Down, and 270-degree: Left
- * @param direction The near object in one direction
- * @param weight The weight is bigger when the object is located near
- * @return EINA_TRUE if near object is updated.
- *
- * @ingroup Widget
- */
-
-EOLIAN static Eina_Bool
-_elm_widget_focus_direction_get(const Eo *obj, Elm_Widget_Smart_Data *sd, const Evas_Object *base, double degree, Evas_Object **direction, Elm_Object_Item **direction_item, double *weight)
-{
- double c_weight;
-
- /* -1 means the best was already decided. Don't need any more searching. */
- if (!direction || !weight || !base || (obj == base))
- return EINA_FALSE;
-
- /* Ignore if disabled */
- if ((!evas_object_visible_get(obj))
- || (elm_widget_disabled_get(obj))
- || (elm_widget_tree_unfocusable_get(obj)))
- return EINA_FALSE;
-
- /* Try use hook */
- if (_internal_elm_widget_focus_direction_manager_is(obj))
- {
- Eina_Bool int_ret = EINA_FALSE;
- int_ret = elm_obj_widget_focus_direction((Eo *)obj, base, degree, direction, direction_item, weight);
- return int_ret;
- }
-
- if (!elm_widget_can_focus_get(obj) || _is_focused((Eo *)obj))
- return EINA_FALSE;
-
- c_weight = _elm_widget_focus_direction_weight_get(base, obj, degree);
- if ((c_weight == -1.0) ||
- ((c_weight != 0.0) && (*weight != -1.0) &&
- ((int)(*weight * 1000000) <= (int)(c_weight * 1000000))))
- {
- if (*direction &&
- ((int)(*weight * 1000000) == (int)(c_weight * 1000000)))
- {
- ELM_WIDGET_DATA_GET(*direction, sd1);
- if (sd1)
- {
- if (sd->focus_order <= sd1->focus_order)
- return EINA_FALSE;
- }
- }
- *direction = (Evas_Object *)obj;
- *weight = c_weight;
- return EINA_TRUE;
- }
-
- return EINA_FALSE;
-}
-
-/**
- * @internal
- *
- * Get near object in one direction of base object in list.
- *
- * Get near object in one direction of base object in the specific
- * object list. Return the near object by reference.
- * By initializing weight, you can filter objects locating far
- * from base object. If object is in the specific direction,
- * weight is (1/(distance^2)). If object is not exactly in one
- * direction, some penalty will be added.
- *
- * @param obj The widget root of sub-tree
- * @param base The base object of the direction
- * @param items list with ordered objects
- * @param list_data_get function to get the object from one item of list
- * @param degree Degree changes clockwise. i.e. 0-degree: Up,
- * 90-degree: Right, 180-degree: Down, and 270-degree: Left
- * @param direction The near object in one direction
- * @param weight The weight is bigger when the object is located near
- * @return EINA_TRUE if near object is updated.
- *
- * @ingroup Widget
- */
-EAPI Eina_Bool
-elm_widget_focus_list_direction_get(const Eo *obj EINA_UNUSED, const Evas_Object *base, const Eina_List *items, list_data_get_func_type list_data_get, double degree, Evas_Object **direction, Elm_Object_Item **direction_item, double *weight)
-{
- if (!direction || !weight || !base || !items)
- return EINA_FALSE;
-
- const Eina_List *l = items;
- Evas_Object *current_best = *direction;
-
- for (; l; l = eina_list_next(l))
- {
- Evas_Object *cur = list_data_get(l);
- if (cur && _elm_widget_is(cur))
- elm_obj_widget_focus_direction_get(cur, base, degree, direction, direction_item, weight);
- }
- if (current_best != *direction) return EINA_TRUE;
-
- return EINA_FALSE;
-}
-
-/**
- * @internal
- *
- * Get next object in focus chain of object tree.
- *
- * Get next object in focus chain of one object sub-tree.
- * Return the next object by reference. If don't have any candidate to receive
- * focus before chain end, the first candidate will be returned.
- *
- * @param obj The widget root of sub-tree
- * @param dir Direction of focus chain
- * @param next The next object in focus chain
- * @return EINA_TRUE if don't need focus chain restart/loop back
- * to use 'next' obj.
- *
- * @ingroup Widget
- */
-EOLIAN static Eina_Bool
-_elm_widget_focus_next_get(const Eo *obj, Elm_Widget_Smart_Data *sd, Elm_Focus_Direction dir, Evas_Object **next, Elm_Object_Item **next_item)
-{
- Elm_Access_Info *ac;
-
- if (!next)
- return EINA_FALSE;
- *next = NULL;
-
- /* Ignore if disabled */
- if (_elm_config->access_mode && _elm_access_auto_highlight_get())
- {
- if (!evas_object_visible_get(obj)
- || (elm_widget_tree_unfocusable_get(obj)))
- return EINA_FALSE;
- }
- else
- {
- if ((!evas_object_visible_get(obj))
- || (elm_widget_disabled_get(obj))
- || (elm_widget_tree_unfocusable_get(obj)))
- return EINA_FALSE;
- }
-
- /* Try use hook */
- if (_elm_widget_focus_chain_manager_is(obj))
- {
- Eina_Bool int_ret = EINA_FALSE;
- int_ret = elm_obj_widget_focus_next((Eo *)obj, dir, next, next_item);
- if (!int_ret && _is_focused((Eo *)obj))
- {
- Evas_Object *o = NULL;
- if (dir == ELM_FOCUS_PREVIOUS)
- *next_item = sd->item_focus_previous;
- else if (dir == ELM_FOCUS_NEXT)
- *next_item = sd->item_focus_next;
- else if (dir == ELM_FOCUS_UP)
- *next_item = sd->item_focus_up;
- else if (dir == ELM_FOCUS_DOWN)
- *next_item = sd->item_focus_down;
- else if (dir == ELM_FOCUS_RIGHT)
- *next_item = sd->item_focus_right;
- else if (dir == ELM_FOCUS_LEFT)
- *next_item = sd->item_focus_left;
- if (*next_item)
- o = elm_object_item_widget_get(*next_item);
-
- if (!o)
- {
- 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;
- }
- }
- return int_ret;
- }
-
- /* access object does not check sd->can_focus, because an object could
- have highlight even though the object is not focusable. */
- if (_elm_config->access_mode && _elm_access_auto_highlight_get())
- {
- ac = _elm_access_info_get(obj);
- if (!ac) return EINA_FALSE;
-
- /* check whether the hover object is visible or not */
- if (!evas_object_visible_get(ac->hoverobj))
- return EINA_FALSE;
- }
- else if (!elm_widget_can_focus_get(obj))
- return EINA_FALSE;
-
- if (_is_focused((Eo *)obj))
- {
- if (dir == ELM_FOCUS_PREVIOUS)
- *next_item = sd->item_focus_previous;
- else if (dir == ELM_FOCUS_NEXT)
- *next_item = sd->item_focus_next;
- else if (dir == ELM_FOCUS_UP)
- *next_item = sd->item_focus_up;
- else if (dir == ELM_FOCUS_DOWN)
- *next_item = sd->item_focus_down;
- else if (dir == ELM_FOCUS_RIGHT)
- *next_item = sd->item_focus_right;
- else if (dir == ELM_FOCUS_LEFT)
- *next_item = sd->item_focus_left;
- if (*next_item) *next = elm_object_item_widget_get(*next_item);
-
- if (!(*next))
- {
- 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);
-}
-
-/**
- * @internal
- *
- * Get next object in focus chain of object tree in list.
- *
- * Get next object in focus chain of one object sub-tree ordered by one list.
- * Return the next object by reference. If don't have any candidate to receive
- * focus before list end, the first candidate will be returned.
- *
- * @param obj The widget root of sub-tree
- * @param items list with ordered objects
- * @param list_data_get function to get the object from one item of list
- * @param dir Direction of focus chain
- * @param next The next object in focus chain
- * @return EINA_TRUE if don't need focus chain restart/loop back
- * to use 'next' obj.
- *
- * @ingroup Widget
- */
-EAPI Eina_Bool
-elm_widget_focus_list_next_get(const Eo *obj, const Eina_List *items, list_data_get_func_type list_data_get, Elm_Focus_Direction dir, Evas_Object **next, Elm_Object_Item **next_item)
-{
- Eina_List *(*list_next)(const Eina_List *list) = NULL;
- Evas_Object *focused_object = NULL;
-
- if (!next)
- return EINA_FALSE;
- *next = NULL;
-
- if (!_elm_widget_is(obj))
- return EINA_FALSE;
-
- if (!items)
- return EINA_FALSE;
-
- /* When Up, Down, Right, or Left, try direction_get first. */
- focused_object = elm_obj_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_item = elm_obj_widget_focus_next_item_get(focused_object, dir);
- if (*next_item)
- *next = elm_object_item_widget_get(*next_item);
- else
- *next = elm_obj_widget_focus_next_object_get(focused_object, dir);
- if (*next) return EINA_TRUE;
- else
- {
- Evas_Object *n = NULL;
- Elm_Object_Item *n_item = NULL;
- double degree = 0;
- double weight = 0.0;
-
- 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, &n_item,
- &weight))
- {
- *next_item = n_item;
- *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)
- || (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;
-
- const Eina_List *l = items;
-
- /* Recovery last focused sub item */
- if (ELM_WIDGET_FOCUS_GET(obj))
+ else
{
- for (; l; l = list_next(l))
+ int j = 0, k = 0;
+ double sx[4] = {0.0, 0.0, 0.0, 0.0}, sy[4] = {0.0, 0.0, 0.0, 0.0};
+ double t_weight[4] = {-1.0, -1.0, -1.0, -1.0};
+ if ((_R(g * x2) >= _R(yy2)) && (_R(g * x2) <= _R(yyy2)))
{
- Evas_Object *cur = list_data_get(l);
- if (ELM_WIDGET_FOCUS_GET(cur)) break;
+ sx[j] = x2;
+ sy[j] = g * x2;
+ t_weight[j++] = ((ax - x2) * (ax - x2)) +
+ ((ay - (g * x2)) * (ay - (g * x2)));
}
-
- /* Focused object, but no focused sub item */
- if (!l) l = items;
- }
-
- const Eina_List *start = l;
- Evas_Object *to_focus = NULL;
- Elm_Object_Item *to_focus_item = NULL;
-
- /* Iterate sub items */
- /* Go to the end of list */
- for (; l; l = list_next(l))
- {
- Evas_Object *tmp = NULL;
- Elm_Object_Item *tmp_item = NULL;
- Evas_Object *cur = list_data_get(l);
-
- if (!cur) continue;
- if (!_elm_widget_is(cur)) continue;
- if (elm_widget_parent_get(cur) != obj)
- continue;
-
- /* Try Focus cycle in subitem */
- if (elm_obj_widget_focus_next_get(cur, dir, &tmp, &tmp_item))
+ if ((_R(g * xx2) >= _R(yy2)) && (_R(g * xx2) <= _R(yyy2)))
{
- *next = tmp;
- *next_item = tmp_item;
- return EINA_TRUE;
+ sx[j] = xx2;
+ sy[j] = g * xx2;
+ t_weight[j++] = ((ax - xx2) * (ax - xx2)) +
+ ((ay - (g * xx2)) * (ay - (g * xx2)));
}
- else if ((dir == ELM_FOCUS_UP)
- || (dir == ELM_FOCUS_DOWN)
- || (dir == ELM_FOCUS_RIGHT)
- || (dir == ELM_FOCUS_LEFT))
+ if ((_R((1.0 / g) * yy2) >= _R(x2)) && (_R((1.0 / g) * yy2) <= _R(xx2)))
{
- if (tmp && _is_focused(cur))
- {
- *next = tmp;
- *next_item = tmp_item;
- return EINA_FALSE;
- }
+ sx[j] = (1.0 / g) * yy2;
+ sy[j] = yy2;
+ t_weight[j++] =
+ ((ax - ((1.0 / g) * yy2)) * (ax - ((1.0 / g) * yy2))) +
+ ((ay - yy2) * (ay - yy2));
}
- else if ((tmp) && (!to_focus))
+ if ((_R((1.0 / g) * yyy2) >= _R(x2)) && (_R((1.0 / g) * yyy2)
+ <= _R(xx2)))
{
- to_focus = tmp;
- to_focus_item = tmp_item;
+ sx[j] = (1.0 / g) * yyy2;
+ sy[j] = yyy2;
+ t_weight[j++] =
+ ((ax - ((1.0 / g) * yyy2)) * (ax - ((1.0 / g) * yyy2))) +
+ ((ay - yyy2) * (ay - yyy2));
}
- }
-
- l = items;
-
- /* Get First possible */
- for (; l != start; l = list_next(l))
- {
- Evas_Object *tmp = NULL;
- Elm_Object_Item *tmp_item = NULL;
- Evas_Object *cur = list_data_get(l);
- if (elm_widget_parent_get(cur) != obj)
- continue;
-
- /* Try Focus cycle in subitem */
- elm_obj_widget_focus_next_get(cur, dir, &tmp, &tmp_item);
- if (tmp)
+ if ((j > 2) || ((j == 2) && ((_R(sx[0]) != _R(sx[1])) ||
+ (_R(sy[0]) != _R(sy[1])))))
{
- *next = tmp;
- *next_item = tmp_item;
- return EINA_FALSE;
+ for (; k < j; k++)
+ {
+ if (_R(t_weight[k]) == 0) return -1.0;
+ if ((1 / weight) < (1 / t_weight[k])) weight = t_weight[k];
+ }
+ }
+ else
+ {
+ for (; k < i; k++)
+ {
+ double ccx, ccy, t1_weight, x_diff, y_diff;
+ ccx = ((1.0 / g) * rx[k] + ry[k]) / (g + (1.0 / g));
+ ccy = g * ccx;
+ x_diff = rx[k] - ccx;
+ if (x_diff < 0) x_diff *= -1.0;
+ y_diff = ry[k] - ccy;
+ if (y_diff < 0) y_diff *= -1.0;
+ t1_weight =
+ (((ax - ccx) * (ax - ccx)) + ((ay - ccy) * (ay - ccy))) +
+ ((x_diff * x_diff * x_diff) + (y_diff * y_diff * y_diff));
+ if ((_R(t1_weight) != 0) && ((1 / weight) < (1 / t1_weight)))
+ weight = t1_weight;
+ }
}
}
+ /* Return the current object's weight. */
+ if (weight == -1.0) return 0.0;
+ if (_R(weight) == 0) return -1.0;
- *next = to_focus;
- *next_item = to_focus_item;
- return EINA_FALSE;
-}
-
-/**
- * @internal
- *
- * Get next object which was set with specific focus direction.
- *
- * Get next object which was set by elm_obj_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
- */
-EOLIAN static Evas_Object*
-_elm_widget_focus_next_object_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, Elm_Focus_Direction dir)
-{
- Evas_Object *ret = NULL;
-
- if (dir == ELM_FOCUS_PREVIOUS)
- ret = sd->focus_previous;
- else if (dir == ELM_FOCUS_NEXT)
- ret = sd->focus_next;
- else if (dir == ELM_FOCUS_UP)
- ret = sd->focus_up;
- else if (dir == ELM_FOCUS_DOWN)
- ret = sd->focus_down;
- else if (dir == ELM_FOCUS_RIGHT)
- ret = sd->focus_right;
- else if (dir == ELM_FOCUS_LEFT)
- ret = sd->focus_left;
-
- return ret;
-}
-
-/**
- * @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
- */
-EOLIAN static void
-_elm_widget_focus_next_object_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, Evas_Object *next, Elm_Focus_Direction dir)
-{
-
- 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;
-}
-
-EOLIAN static Elm_Object_Item*
-_elm_widget_focus_next_item_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, Elm_Focus_Direction dir)
-{
- Elm_Object_Item *ret = NULL;
-
- if (dir == ELM_FOCUS_PREVIOUS)
- ret = sd->item_focus_previous;
- else if (dir == ELM_FOCUS_NEXT)
- ret = sd->item_focus_next;
- else if (dir == ELM_FOCUS_UP)
- ret = sd->item_focus_up;
- else if (dir == ELM_FOCUS_DOWN)
- ret = sd->item_focus_down;
- else if (dir == ELM_FOCUS_RIGHT)
- ret = sd->item_focus_right;
- else if (dir == ELM_FOCUS_LEFT)
- ret = sd->item_focus_left;
-
- return ret;
-}
+#undef _R
-EOLIAN static void
-_elm_widget_focus_next_item_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, Elm_Object_Item *next_item, Elm_Focus_Direction dir)
-{
- if (dir == ELM_FOCUS_PREVIOUS)
- sd->item_focus_previous = next_item;
- else if (dir == ELM_FOCUS_NEXT)
- sd->item_focus_next = next_item;
- else if (dir == ELM_FOCUS_UP)
- sd->item_focus_up = next_item;
- else if (dir == ELM_FOCUS_DOWN)
- sd->item_focus_down = next_item;
- else if (dir == ELM_FOCUS_RIGHT)
- sd->item_focus_right = next_item;
- else if (dir == ELM_FOCUS_LEFT)
- sd->item_focus_left = next_item;
+ return 1.0 / weight;
}
/** @internal */
return sd->parent_obj;
}
-static void
-_focused_object_clear(Elm_Widget_Smart_Data *sd)
-{
- if (sd->resize_obj && elm_widget_is(sd->resize_obj) &&
- _is_focused(sd->resize_obj))
- {
- elm_obj_widget_focused_object_clear(sd->resize_obj);
- }
- else
- {
- const Eina_List *l;
- Evas_Object *child;
- EINA_LIST_FOREACH(sd->subobjs, l, child)
- {
- if (_elm_widget_is(child) && _is_focused(child))
- {
- elm_obj_widget_focused_object_clear(child);
- break;
- }
- }
- }
-}
-
-EOLIAN static void
-_elm_widget_focused_object_clear(Eo *obj, Elm_Widget_Smart_Data *sd)
-{
- if (!sd->focused) return;
- _focused_object_clear(sd);
- sd->focused = EINA_FALSE;
- if (sd->top_win_focused)
- elm_obj_widget_on_focus_update(obj, NULL);
-}
-
-static Eo *
-elm_widget_parent2_get(Eo *obj)
-{
- if (!efl_isa(obj, EFL_UI_WIN_INLINED_CLASS)) return NULL;
- return efl_ui_win_inlined_parent_get(obj);
-}
-
-EOLIAN static void
-_elm_widget_focus_steal(Eo *obj, Elm_Widget_Smart_Data *sd, Elm_Object_Item *item)
-{
- Evas_Object *parent, *parent2, *o;
-
- if (sd->focused) return;
- if (sd->disabled) return;
- if (!sd->can_focus) return;
- if (sd->tree_unfocusable) return;
- parent = obj;
- for (;; )
- {
- o = elm_widget_parent_get(parent);
- if (!o) break;
- sd = efl_data_scope_get(o, MY_CLASS);
- if (sd->disabled || sd->tree_unfocusable) return;
- if (sd->focused) break;
- parent = o;
- }
- if ((!elm_widget_parent_get(parent)) &&
- (!elm_widget_parent2_get(parent)))
- elm_obj_widget_focused_object_clear(parent);
- else
- {
- parent2 = elm_widget_parent_get(parent);
- if (!parent2) parent2 = elm_widget_parent2_get(parent);
- parent = parent2;
- sd = efl_data_scope_get(parent, MY_CLASS);
- if (sd) _focused_object_clear(sd);
- }
- _parent_focus(obj, item);
- elm_widget_focus_region_show(obj);
- return;
-}
-
-static void
-_parents_on_focus(Evas_Object *obj)
-{
- API_ENTRY return;
- if (!sd->focused || !sd->top_win_focused) return;
-
- Evas_Object *o = elm_widget_parent_get(obj);
- if (o) _parents_on_focus(o);
- elm_obj_widget_on_focus_update(obj, NULL);
-}
-
-EOLIAN static void
-_elm_widget_focus_restore(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
-{
- Evas_Object *newest = NULL;
- unsigned int newest_focus_order = 0;
-
- newest = elm_widget_newest_focus_order_get(obj, &newest_focus_order, EINA_TRUE);
- if (newest)
- _parents_on_focus(newest);
-}
-
void
_elm_widget_focus_auto_show(Evas_Object *obj)
{
{
if (elm_widget_is(child))
{
- elm_obj_widget_focus_disabled_handle(child);
elm_obj_widget_on_disabled_update(child, disabled);
_elm_widget_disabled_eval(child, disabled);
}
if (!disabled && elm_widget_disabled_get(elm_widget_parent_get(obj)))
return;
- elm_obj_widget_focus_disabled_handle(obj);
elm_obj_widget_on_disabled_update(obj, disabled);
_elm_widget_disabled_eval(obj, disabled);
}
efl_event_callback_legacy_call(obj, ELM_WIDGET_EVENT_LANGUAGE_CHANGED, NULL);
}
-/**
- * @internal
- *
- * Resets the focus_move_policy mode from the system one
- * for widgets that are in automatic mode.
- *
- * @param obj The widget.
- *
- */
-static void
-_elm_widget_focus_move_policy_reload(Evas_Object *obj)
-{
- API_ENTRY return;
- Elm_Focus_Move_Policy focus_move_policy = elm_config_focus_move_policy_get();
-
- if (elm_obj_widget_focus_move_policy_automatic_get(obj) &&
- (sd->focus_move_policy != focus_move_policy))
- {
- sd->focus_move_policy = focus_move_policy;
- }
-}
-
-EOLIAN static void
-_elm_widget_focus_reconfigure(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
-{
- const Eina_List *l;
- Evas_Object *child;
- API_ENTRY return;
-
- EINA_LIST_FOREACH(sd->subobjs, l, child)
- {
- if (elm_widget_is(child))
- elm_obj_widget_focus_reconfigure(child);
- }
-
- if (sd->hover_obj) elm_obj_widget_focus_reconfigure(sd->hover_obj);
-
- _elm_widget_focus_move_policy_reload(obj);
-}
-
EOLIAN static void
_elm_widget_access_info_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, const char *txt)
{
eina_stringshare_del(s);
}
-EOLIAN static void
-_elm_widget_focus_hide_handle(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
-{
- if (!_elm_widget_is(obj))
- return;
- _if_focused_revert(obj, EINA_TRUE);
-}
-
/* internal */
EAPI void
elm_widget_focus_mouse_up_handle(Eo *obj)
if (!_is_focusable(obj)) return;
- elm_obj_widget_focus_steal(obj, NULL);
-
if (pd->focus.manager && !pd->focus.logical)
{
Efl_Ui_Focus_Manager *m, *m2 = obj, *old = NULL;
}
static void
-_elm_widget_focus_tree_unfocusable_handle(Eo *obj)
-{
- if (!elm_widget_parent_get(obj))
- elm_obj_widget_focused_object_clear(obj);
- else
- _if_focused_revert(obj, EINA_TRUE);
-}
-
-EOLIAN static void
-_elm_widget_focus_disabled_handle(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
-{
- _elm_widget_focus_tree_unfocusable_handle(obj);
-}
-
-EOLIAN static unsigned int
-_elm_widget_focus_order_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
-{
- return sd->focus_order;
-}
-
-EAPI Evas_Object*
-elm_widget_newest_focus_order_get(const Eo *obj, unsigned int *newest_focus_order, Eina_Bool can_focus_only)
+_elm_widget_focus_tree_unfocusable_handle(Eo *obj EINA_UNUSED)
{
- Elm_Widget_Smart_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
- const Eina_List *l;
- Evas_Object *child, *cur, *best;
-
- if (!sd) 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)
- {
- if (!can_focus_only || elm_widget_can_focus_get(obj))
- {
- *newest_focus_order = sd->focus_order;
- best = (Evas_Object *)obj;
- }
- }
- EINA_LIST_FOREACH(sd->subobjs, l, child)
- {
- if (!_elm_widget_is(child)) continue;
-
- cur = elm_widget_newest_focus_order_get
- (child, newest_focus_order, can_focus_only);
- if (!cur) continue;
- best = cur;
- }
- return best;
+ //FIXME
}
/*
}
EOLIAN static Eina_Bool
-_elm_widget_focus_next_manager_is(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
-{
- WRN("The %s widget does not implement the \"focus_next/focus_next_manager_is\" functions.",
- efl_class_name_get(efl_class_get(obj)));
- return EINA_FALSE;
-}
-
-static Eina_Bool
-_elm_widget_focus_direction_manager_is(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
-{
- WRN("The %s widget does not implement the \"focus_direction/focus_direction_manager_is\" functions.",
- efl_class_name_get(efl_class_get(obj)));
- return EINA_FALSE;
-}
-
-EOLIAN static Eina_Bool
_elm_widget_on_access_activate(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED, Elm_Activate act EINA_UNUSED)
{
WRN("The %s widget does not implement the \"activate\" functions.",