Eina_Bool preset : 1;
};
-/***********************************************************
- * TIZEN_ONLY(20180117): Override Paragraph Direction APIs *
- ***********************************************************/
-static void
-_efl_ui_widget_efl_canvas_object_paragraph_direction_set_internal(Eo *obj EINA_UNUSED, Efl_Ui_Widget_Data *sd, Evas_BiDi_Direction dir);
-/*******
- * END *
- *******/
+// TIZEN_ONLY PROTOTYPES
+static void _efl_ui_widget_efl_canvas_object_paragraph_direction_set_internal(Eo *obj EINA_UNUSED, Efl_Ui_Widget_Data *sd, Evas_BiDi_Direction dir); // TIZEN_ONLY(20180117): Override Paragraph Direction APIs
+static void _if_focused_revert(Evas_Object *obj, Eina_Bool can_focus_only); //TIZEN_ONLY(20180607): Restore legacy focus
+
+static void elm_widget_disabled_internal(Eo *obj, Eina_Bool disabled);
+static void _on_sub_obj_hide(void *data, const Efl_Event *event);
+
+static inline Eina_Bool _elm_widget_focus_chain_manager_is(const Evas_Object *obj);
+static inline Eina_Bool _internal_elm_widget_focus_direction_manager_is(const Evas_Object *obj);
+static void _parent_focus(Evas_Object *obj, Elm_Object_Item *item);
+static void _elm_object_focus_chain_del_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED);
+
+static Eina_List *_lines_split(Eina_List *children);
+static int _sort_vertically(const void *data1, const void *data2);
+static int _sort_horizontally(const void *data1, const void *data2);
+
+Eo * plug_type_proxy_get(Eo *obj, Evas_Object *widget);
+
+static Eina_Bool _elm_widget_can_highlight_get_by_class(Eo *obj);
+static Eina_Bool _accessible_object_on_scroll_is(Eo* obj);
+// TIZEN_ONLY
+
+
+
/* For keeping backward compatibility (EFL 1.18 or older versions).
* Since EFL 1.19 which starts to use eolian_gen2, it does not convert
efl_isa(obj, EFL_UI_SCROLLABLE_INTERACTIVE_INTERFACE);
}
-static void
-elm_widget_disabled_internal(Eo *obj, Eina_Bool disabled);
-static void
-_on_sub_obj_del(void *data, const Efl_Event *event);
-//TIZEN_ONLY(20180607): Restore legacy focus
-static void
-_on_sub_obj_hide(void *data, const Efl_Event *event);
-//
+static void _on_sub_obj_del(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);
static void _elm_widget_shadow_update(Efl_Ui_Widget *obj);
evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_IN,
_obj_mouse_in, obj);
}
-//TIZEN_ONLY(20180607): Restore legacy focus
-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 = efl_ui_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))
- efl_ui_widget_focus_steal(newest, NULL);
- else
- {
- if (sd2->resize_obj && _is_focused(sd2->resize_obj))
- efl_ui_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))
- {
- efl_ui_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
_efl_ui_widget_efl_canvas_group_group_del(Eo *obj, Elm_Widget_Smart_Data *sd)
{
}
// internal funcs
-//TIZEN_ONLY(20180607): Restore legacy focus
-/**
- * @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 = efl_ui_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 = efl_ui_widget_focus_direction_manager_is((Eo *)obj);
- return manager_is;
-}
-
-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)
- efl_ui_focus_object_on_focus_update(obj);
- 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);
-}
-//
-
-// internal funcs
static void
_propagate_x_drag_lock(Evas_Object *obj,
int dir)
}
}
-//TIZEN_ONLY(20180607): Restore legacy focus
-/**
- * @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
-_efl_ui_widget_focus_custom_chain_set(Eo *obj, Elm_Widget_Smart_Data *sd, Eina_List *objs)
+double
+_elm_widget_focus_direction_weight_get(const Evas_Object *obj1,
+ const Evas_Object *obj2,
+ double degree)
{
- if (!_elm_widget_focus_chain_manager_is(obj)) return;
-
- efl_ui_widget_focus_custom_chain_unset(obj);
+ Evas_Coord obj_x1, obj_y1, w1, h1, obj_x2, obj_y2, w2, h2;
+ double x1, yy1, x2, yy2, xx1, yyy1, xx2, yyy2;
+ double ax, ay, cx, cy;
+ double weight = -1.0, g = 0.0;
+ // TIZEN_ONLY(20171129): add second_level for weight calculate
+ Eina_Bool second_level = EINA_FALSE;
+ //
- Eina_List *l;
- Evas_Object *o;
+ if (obj1 == obj2) return 0.0;
- EINA_LIST_FOREACH(objs, l, o)
- {
- evas_object_event_callback_add(o, EVAS_CALLBACK_DEL,
- _elm_object_focus_chain_del_cb, obj);
- }
+ degree -= 90.0;
+ while (degree >= 360.0)
+ degree -= 360.0;
+ while (degree < 0.0)
+ degree += 360.0;
- sd->focus_chain = objs;
-}
+ evas_object_geometry_get(obj1, &obj_x1, &obj_y1, &w1, &h1);
+ cx = obj_x1 + (w1 / 2.0);
+ cy = obj_y1 + (h1 / 2.0);
+ evas_object_geometry_get(obj2, &obj_x2, &obj_y2, &w2, &h2);
-/**
- * @internal
- *
- * Get custom focus chain
- *
- * @param obj The container widget
- * @ingroup Widget
- */
-EOLIAN static const Eina_List*
-_efl_ui_widget_focus_custom_chain_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
-{
- return (const Eina_List *)sd->focus_chain;
-}
+ /* For overlapping cases. */
+ if (ELM_RECTS_INTERSECT(obj_x1, obj_y1, w1, h1, obj_x2, obj_y2, w2, h2))
+ return 0.0;
-/**
- * @internal
- *
- * Unset custom focus chain
- *
- * @param obj The container widget
- * @ingroup Widget
- */
-EOLIAN static void
-_efl_ui_widget_focus_custom_chain_unset(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
-{
- Eina_List *l, *l_next;
- Evas_Object *o;
+ /* Change all points to relative one. */
+ x1 = obj_x1 - cx;
+ xx1 = x1 + w1;
+ yy1 = obj_y1 - cy;
+ yyy1 = yy1 + h1;
+ x2 = obj_x2 - cx;
+ xx2 = x2 + w2;
+ yy2 = obj_y2 - cy;
+ yyy2 = yy2 + h2;
- EINA_LIST_FOREACH_SAFE(sd->focus_chain, l, l_next, o)
+ /* Get crossing points (ax, ay) between obj1 and a line extending
+ * to the direction of current degree. */
+ if (degree == 0.0)
{
- 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
-_efl_ui_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
-_efl_ui_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
-_efl_ui_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;
- efl_ui_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())
- efl_ui_widget_focus_steal(target, target_item);
-
- _elm_access_highlight_set(target);
- elm_widget_focus_region_show(target);
- }
- else efl_ui_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
-_efl_ui_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 = efl_ui_widget_focused_object_get(obj);
-
- if (efl_ui_widget_focus_direction_get
- (obj, current_focused, degree, &target, &target_item, &weight))
- {
- efl_ui_widget_focus_steal(target, NULL);
- return EINA_TRUE;
- }
-
- return EINA_FALSE;
-}
-//END
-
-double
-_elm_widget_focus_direction_weight_get(const Evas_Object *obj1,
- const Evas_Object *obj2,
- double degree)
-{
- Evas_Coord obj_x1, obj_y1, w1, h1, obj_x2, obj_y2, w2, h2;
- double x1, yy1, x2, yy2, xx1, yyy1, xx2, yyy2;
- double ax, ay, cx, cy;
- double weight = -1.0, g = 0.0;
- // TIZEN_ONLY(20171129): add second_level for weight calculate
- Eina_Bool second_level = EINA_FALSE;
- //
-
- if (obj1 == obj2) return 0.0;
-
- degree -= 90.0;
- while (degree >= 360.0)
- degree -= 360.0;
- while (degree < 0.0)
- degree += 360.0;
-
- evas_object_geometry_get(obj1, &obj_x1, &obj_y1, &w1, &h1);
- cx = obj_x1 + (w1 / 2.0);
- cy = obj_y1 + (h1 / 2.0);
- evas_object_geometry_get(obj2, &obj_x2, &obj_y2, &w2, &h2);
-
- /* For overlapping cases. */
- if (ELM_RECTS_INTERSECT(obj_x1, obj_y1, w1, h1, obj_x2, obj_y2, w2, h2))
- return 0.0;
-
- /* Change all points to relative one. */
- x1 = obj_x1 - cx;
- xx1 = x1 + w1;
- yy1 = obj_y1 - cy;
- yyy1 = yy1 + h1;
- x2 = obj_x2 - cx;
- xx2 = x2 + w2;
- yy2 = obj_y2 - cy;
- yyy2 = yy2 + h2;
-
- /* Get crossing points (ax, ay) between obj1 and a line extending
- * to the direction of current degree. */
- if (degree == 0.0)
- {
- ax = xx1;
- ay = 0.0;
+ ax = xx1;
+ ay = 0.0;
}
else if (degree == 90.0)
{
return 1.0 / weight;
}
-//TIZEN_ONLY(20180607): Restore legacy focus
-/**
- * @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
-_efl_ui_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)
+/** @internal */
+EAPI void
+elm_widget_parent_highlight_set(Eo *obj, Eina_Bool highlighted)
{
- double c_weight;
+ Elm_Widget_Smart_Data *sd =efl_data_scope_safe_get(obj, MY_CLASS);
+ if (!sd) return;
- /* -1 means the best was already decided. Don't need any more searching. */
- if (!direction || !weight || !base || (obj == base))
- return EINA_FALSE;
+ highlighted = !!highlighted;
- /* Ignore if disabled */
- if ((!evas_object_visible_get(obj))
- || (elm_widget_disabled_get(obj))
- || (elm_widget_tree_unfocusable_get(obj)))
- return EINA_FALSE;
+ Evas_Object *o = elm_widget_parent_get(obj);
- /* Try use hook */
- if (_internal_elm_widget_focus_direction_manager_is(obj))
- {
- Eina_Bool int_ret = EINA_FALSE;
- int_ret = efl_ui_widget_focus_direction((Eo *)obj, base, degree, direction, direction_item, weight);
- return int_ret;
- }
+ if (o) elm_widget_parent_highlight_set(o, highlighted);
- if (!elm_widget_can_focus_get(obj) || _is_focused((Eo *)obj))
- return EINA_FALSE;
+ sd->highlighted = highlighted;
+}
- 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;
+EOLIAN static Evas_Object*
+_efl_ui_widget_widget_parent_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
+{
+ return sd->parent_obj;
}
-/**
- * @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
- */
-EOLIAN static Eina_Bool
-_efl_ui_widget_focus_list_direction_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED, const Evas_Object *base, const Eina_List *items, void* list_data_get, double degree, Evas_Object **direction, Elm_Object_Item **direction_item, double *weight)
+void
+_elm_widget_focus_auto_show(Evas_Object *obj)
{
- if (!direction || !weight || !base || !items)
- return EINA_FALSE;
+ Evas_Object *top = elm_widget_top_get(obj);
+ if (top && efl_isa(top, EFL_UI_WIN_CLASS)) _elm_win_focus_auto_show(top);
+}
- const Eina_List *l = items;
- Evas_Object *current_best = *direction;
+void
+_elm_widget_top_win_focused_set(Evas_Object *obj,
+ Eina_Bool top_win_focused)
+{
+ const Eina_List *l;
+ Evas_Object *child;
+ API_ENTRY return;
- for (; l; l = eina_list_next(l))
+ if (sd->top_win_focused == top_win_focused) return;
+ EINA_LIST_FOREACH(sd->subobjs, l, child)
{
- Evas_Object *cur = ((list_data_get_func_type)list_data_get)(l);
- if (cur && _elm_widget_is(cur))
- efl_ui_widget_focus_direction_get(cur, base, degree, direction, direction_item, weight);
+ if (elm_widget_is(child))
+ _elm_widget_top_win_focused_set(child, top_win_focused);
}
- if (current_best != *direction) return EINA_TRUE;
+ sd->top_win_focused = top_win_focused;
+
+ if (sd->focused && !sd->top_win_focused)
+ efl_ui_focus_object_on_focus_update(obj);
+}
+
+Eina_Bool
+_elm_widget_top_win_focused_get(const Evas_Object *obj)
+{
+ API_ENTRY return EINA_FALSE;
+ return sd->top_win_focused;
+}
+
+EOLIAN static void
+_efl_ui_widget_disabled_set(Eo *obj, Elm_Widget_Smart_Data *sd, Eina_Bool disabled)
+{
+ if (sd->disabled == disabled) return;
+ sd->disabled = !!disabled;
+
+ elm_widget_disabled_internal(obj, disabled);
+
+ if (efl_finalized_get(obj))
+ _elm_widget_full_eval_children(obj, sd);
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_widget_disabled_get(const Eo *obj, Elm_Widget_Smart_Data *sd)
+{
+ Eo *parent;
+ if (sd->disabled) return EINA_TRUE;
+ if ((parent = elm_widget_parent_get(obj)) != NULL)
+ return elm_widget_disabled_get(parent);
return EINA_FALSE;
}
/**
* @internal
*
- * Get next object in focus chain of object tree.
+ * Get the focus region of the given widget.
*
- * 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.
+ * @return The region to show. If it's not a valid rectangle it will not show.
*
- * @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.
+ * The focus region is the area of a widget that should brought into the
+ * visible area when the widget is focused. Mostly used to show the part of
+ * an entry where the cursor is, for example. The area returned is relative
+ * to the object @p obj.
+ *
+ * @param obj The widget object
+ * @return The region to show, in relative coordinates. If it's not a valid
+ * rectangle (i.e. w or h <= 0) it will be ignored.
*
* @ingroup Widget
*/
-EOLIAN static Eina_Bool
-_efl_ui_widget_focus_next_get(const Eo *obj, Elm_Widget_Smart_Data *sd, Elm_Focus_Direction dir, Evas_Object **next, Elm_Object_Item **next_item)
+EOLIAN static Eina_Rect
+_efl_ui_widget_interest_region_get(const Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
{
- 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;
- }
+ Eina_Rect r = {};
+ r.size = efl_gfx_entity_size_get(obj);
+ return r;
+}
- /* Try use hook */
- if (_elm_widget_focus_chain_manager_is(obj))
+EOLIAN static void
+_efl_ui_widget_scroll_hold_push(Eo *obj, Elm_Widget_Smart_Data *sd)
+{
+ sd->scroll_hold++;
+ if (sd->scroll_hold == 1)
{
- Eina_Bool int_ret = EINA_FALSE;
- int_ret = efl_ui_widget_focus_next((Eo *)obj, dir, next, next_item);
- if (!int_ret && _is_focused((Eo *)obj))
+ if (_elm_scrollable_is(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 (elm_widget_is_legacy(obj))
+ elm_interface_scrollable_hold_set(obj, EINA_TRUE);
+ else
+ efl_ui_scrollable_scroll_hold_set(obj, EINA_TRUE);
+ }
+ else
+ {
+ Evas_Object *child;
+ Eina_List *l;
- if (!o)
+ EINA_LIST_FOREACH(sd->subobjs, l, child)
{
- 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 (elm_widget_is(child) && _elm_scrollable_is(child))
+ {
+ if (elm_widget_is_legacy(obj))
+ elm_interface_scrollable_hold_set(child, EINA_TRUE);
+ else
+ efl_ui_scrollable_scroll_hold_set(child, EINA_TRUE);
+ }
}
+ }
+ }
+ if (sd->parent_obj) efl_ui_widget_scroll_hold_push(sd->parent_obj);
+ // FIXME: on delete/reparent hold pop
+}
- if (o)
+EOLIAN static void
+_efl_ui_widget_scroll_hold_pop(Eo *obj, Elm_Widget_Smart_Data *sd)
+{
+ sd->scroll_hold--;
+ if (!sd->scroll_hold)
+ {
+ if (_elm_scrollable_is(obj))
+ {
+ if (elm_widget_is_legacy(obj))
+ elm_interface_scrollable_hold_set(obj, EINA_FALSE);
+ else
+ efl_ui_scrollable_scroll_hold_set(obj, EINA_FALSE);
+ }
+ else
+ {
+ Evas_Object *child;
+ Eina_List *l;
+
+ EINA_LIST_FOREACH(sd->subobjs, l, child)
{
- *next = o;
- return EINA_TRUE;
+ if (elm_widget_is(child) && _elm_scrollable_is(child))
+ {
+ if (elm_widget_is_legacy(obj))
+ elm_interface_scrollable_hold_set(child, EINA_FALSE);
+ else
+ efl_ui_scrollable_scroll_hold_set(child, EINA_FALSE);
+ }
}
}
- return int_ret;
}
+ if (sd->parent_obj) efl_ui_widget_scroll_hold_pop(sd->parent_obj);
+ if (sd->scroll_hold < 0) sd->scroll_hold = 0;
+}
- /* 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;
+EAPI int
+elm_widget_scroll_hold_get(const Eo *obj)
+{
+ Elm_Widget_Smart_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
- /* 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 (!sd) return 0;
+ return sd->scroll_hold;
+}
- if (_is_focused((Eo *)obj))
+EOLIAN static void
+_efl_ui_widget_scroll_freeze_push(Eo *obj, Elm_Widget_Smart_Data *sd)
+{
+ sd->scroll_freeze++;
+ if (sd->scroll_freeze == 1)
{
- 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 (_elm_scrollable_is(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 (elm_widget_is_legacy(obj))
+ elm_interface_scrollable_freeze_set(obj, EINA_TRUE);
+ else
+ efl_ui_scrollable_scroll_freeze_set(obj, EINA_TRUE);
}
+ else
+ {
+ Evas_Object *child;
+ Eina_List *l;
- if (*next) return EINA_TRUE;
+ EINA_LIST_FOREACH(sd->subobjs, l, child)
+ {
+ if (elm_widget_is(child) && _elm_scrollable_is(child))
+ if (elm_widget_is_legacy(obj))
+ elm_interface_scrollable_freeze_set(child, EINA_TRUE);
+ else
+ efl_ui_scrollable_scroll_freeze_set(child, EINA_TRUE);
+ }
+ }
}
-
- /* Return */
- *next = (Evas_Object *)obj;
- return !ELM_WIDGET_FOCUS_GET(obj);
+ if (sd->parent_obj) efl_ui_widget_scroll_freeze_push(sd->parent_obj);
+ // FIXME: on delete/reparent freeze pop
}
-/**
- * @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
- */
-EOLIAN static Eina_Bool
-_efl_ui_widget_focus_list_next_get(const Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED, const Eina_List *items, void * list_data_get, Elm_Focus_Direction dir, Evas_Object **next, Elm_Object_Item **next_item)
+EOLIAN static void
+_efl_ui_widget_scroll_freeze_pop(Eo *obj, Elm_Widget_Smart_Data *sd)
{
- 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 = efl_ui_widget_focused_object_get(obj);
- if (focused_object)
+ sd->scroll_freeze--;
+ if (!sd->scroll_freeze)
{
- if ((dir == ELM_FOCUS_UP)
- || (dir == ELM_FOCUS_DOWN)
- || (dir == ELM_FOCUS_RIGHT)
- || (dir == ELM_FOCUS_LEFT))
+ if (_elm_scrollable_is(obj))
{
- *next_item = efl_ui_widget_focus_next_item_get(focused_object, dir);
- if (*next_item)
- *next = elm_object_item_widget_get(*next_item);
- else
- *next = efl_ui_widget_focus_next_object_get(focused_object, dir);
- if (*next) return EINA_TRUE;
+ if (elm_widget_is_legacy(obj))
+ elm_interface_scrollable_freeze_set(obj, EINA_FALSE);
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;
+ efl_ui_scrollable_scroll_freeze_set(obj, EINA_FALSE);
+ }
+ else
+ {
+ Evas_Object *child;
+ Eina_List *l;
- if (efl_ui_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;
- }
+ EINA_LIST_FOREACH(sd->subobjs, l, child)
+ {
+ if (elm_widget_is(child) && _elm_scrollable_is(child))
+ if (elm_widget_is_legacy(obj))
+ elm_interface_scrollable_freeze_set(child, EINA_FALSE);
+ else
+ efl_ui_scrollable_scroll_freeze_set(child, EINA_FALSE);
}
}
}
+ if (sd->parent_obj) efl_ui_widget_scroll_freeze_pop(sd->parent_obj);
+ if (sd->scroll_freeze < 0) sd->scroll_freeze = 0;
+}
- /* 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;
+EAPI int
+elm_widget_scroll_freeze_get(const Eo *obj)
+{
+ Elm_Widget_Smart_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
- const Eina_List *l = items;
+ if (!sd) return 0;
+ return sd->scroll_freeze;
+}
- /* Recovery last focused sub item */
- if (ELM_WIDGET_FOCUS_GET(obj))
+EOLIAN static void
+_efl_ui_widget_efl_gfx_entity_scale_set(Eo *obj, Elm_Widget_Smart_Data *sd, double scale)
+{
+ if (scale < 0.0) scale = 0.0;
+ if (sd->scale != scale)
{
- for (; l; l = list_next(l))
- {
- Evas_Object *cur = ((list_data_get_func_type)list_data_get)(l);
- if (ELM_WIDGET_FOCUS_GET(cur)) break;
- }
-
- /* Focused object, but no focused sub item */
- if (!l) l = items;
+ sd->scale = scale;
+ elm_widget_theme(obj);
}
+}
- 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))
+EOLIAN static double
+_efl_ui_widget_efl_gfx_entity_scale_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
+{
+ // FIXME: save walking up the tree by storing/caching parent scale
+ if (sd->scale == 0.0)
{
- Evas_Object *tmp = NULL;
- Elm_Object_Item *tmp_item = NULL;
- Evas_Object *cur = ((list_data_get_func_type)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 (efl_ui_widget_focus_next_get(cur, dir, &tmp, &tmp_item))
- {
- *next = tmp;
- *next_item = tmp_item;
- return EINA_TRUE;
- }
- else if ((dir == ELM_FOCUS_UP)
- || (dir == ELM_FOCUS_DOWN)
- || (dir == ELM_FOCUS_RIGHT)
- || (dir == ELM_FOCUS_LEFT))
+ if (sd->parent_obj && elm_widget_is(sd->parent_obj))
{
- if (tmp && _is_focused(cur))
- {
- *next = tmp;
- *next_item = tmp_item;
- return EINA_FALSE;
- }
+ return efl_gfx_entity_scale_get(sd->parent_obj);
}
- else if ((tmp) && (!to_focus))
+ else
{
- to_focus = tmp;
- to_focus_item = tmp_item;
+ return 1.0;
}
}
+ return sd->scale;
+}
- l = items;
+EAPI void
+elm_widget_theme_set(Evas_Object *obj, Elm_Theme *th)
+{
+ Elm_Widget_Smart_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
+ if (!sd) return;
- /* Get First possible */
- for (; l != start; l = list_next(l))
+ Eina_Bool apply = EINA_FALSE;
+ if (sd->theme != th)
{
- Evas_Object *tmp = NULL;
- Elm_Object_Item *tmp_item = NULL;
- Evas_Object *cur = ((list_data_get_func_type)list_data_get)(l);
-
- if (elm_widget_parent_get(cur) != obj)
- continue;
+ if (elm_widget_theme_get(obj) != th) apply = EINA_TRUE;
+ if (sd->theme) elm_theme_free(sd->theme);
+ sd->theme = th;
+ if (th) efl_ref(th->eo_theme);
+ if (apply) elm_widget_theme(obj);
+ }
+}
- /* Try Focus cycle in subitem */
- efl_ui_widget_focus_next_get(cur, dir, &tmp, &tmp_item);
- if (tmp)
- {
- *next = tmp;
- *next_item = tmp_item;
- return EINA_FALSE;
- }
- }
-
- *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_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*
-_efl_ui_widget_focus_next_object_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, Elm_Focus_Direction dir)
+EAPI void
+elm_widget_part_text_set(Eo *obj, const char *part, const char *label)
{
- 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;
+ /* legacy support: combobox was special (internal entry is text object). */
+ //TIZEN_ONLY(20180426):stop creating unused class.
+ if (efl_isa(obj, EFL_UI_LAYOUT_CLASS))
+ elm_layout_text_set(obj, part, label);
+ else if (efl_isa(obj, ELM_COMBOBOX_CLASS))
+ _elm_combobox_part_text_set(obj, part, label);
+ //
}
-/**
- * @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
-_efl_ui_widget_focus_next_object_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, Evas_Object *next, Elm_Focus_Direction dir)
+EAPI const char*
+elm_widget_part_text_get(const Eo *obj, const char *part)
{
+ /* legacy support: combobox was special (internal entry is text object). */
+ //TIZEN_ONLY(20180426):stop creating unused class.
+ if (efl_isa(obj, EFL_UI_LAYOUT_CLASS))
+ return elm_layout_text_get(obj, part);
+ else if (efl_isa(obj, ELM_COMBOBOX_CLASS))
+ return _elm_combobox_part_text_get(obj, part);
+ //
- 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;
-
+ return NULL;
}
-EOLIAN static Elm_Object_Item*
-_efl_ui_widget_focus_next_item_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, Elm_Focus_Direction dir)
+static Elm_Translate_String_Data *
+_translate_string_data_get(Eina_Inlist *translate_strings, const char *part)
{
- Elm_Object_Item *ret = NULL;
+ Elm_Translate_String_Data *ts;
+ Eina_Stringshare *str;
- 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;
+ if (!translate_strings) return NULL;
- return ret;
+ str = eina_stringshare_add(part);
+ EINA_INLIST_FOREACH(translate_strings, ts)
+ {
+ if (ts->id == str) break;
+ }
-}
+ eina_stringshare_del(str);
-EOLIAN static void
-_efl_ui_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 ts;
}
-EAPI void
-elm_widget_focus_set(Eo *obj, Eina_Bool focus)
+static Elm_Translate_String_Data *
+_part_text_translatable_set(Eina_Inlist **translate_strings, const char *part, Eina_Bool translatable, Eina_Bool preset)
{
- ELM_WIDGET_DATA_GET_OR_RETURN(obj, sd);
- if (!sd->focused)
- {
- focus_order++;
- sd->focus_order = focus_order;
- sd->focused = EINA_TRUE;
- efl_ui_focus_object_on_focus_update(obj);
- }
+ Eina_Inlist *t;
+ Elm_Translate_String_Data *ts;
+ t = *translate_strings;
+ ts = _translate_string_data_get(t, part);
- if (focus)
+ if (translatable)
{
- if ((_is_focusable(sd->resize_obj)) &&
- (!elm_widget_disabled_get(sd->resize_obj)))
- {
- elm_widget_focus_set(sd->resize_obj, focus);
- }
- else
+ if (!ts)
{
- const Eina_List *l;
- Evas_Object *child;
+ ts = ELM_NEW(Elm_Translate_String_Data);
+ if (!ts) return NULL;
- EINA_LIST_FOREACH(sd->subobjs, l, child)
- {
- if (!_elm_widget_is(child)) continue;
- if ((_is_focusable(child)) &&
- (!elm_widget_disabled_get(child)))
- {
- elm_widget_focus_set(child, focus);
- break;
- }
- }
+ ts->id = eina_stringshare_add(part);
+ t = eina_inlist_append(t, (Eina_Inlist*) ts);
}
+ if (preset) ts->preset = EINA_TRUE;
}
- else
+ //Delete this exist one if this part has been not preset.
+ //see elm_widget_part_text_translatable_set()
+ else if (ts && ((preset) || (!ts->preset)))
{
- const Eina_List *l;
- Evas_Object *child;
-
- EINA_LIST_REVERSE_FOREACH(sd->subobjs, l, child)
- {
- if (!_elm_widget_is(child)) continue;
- if ((_is_focusable(child)) &&
- (!elm_widget_disabled_get(child)))
- {
- elm_widget_focus_set(child, focus);
- break;
- }
- }
+ t = eina_inlist_remove(t, EINA_INLIST_GET(ts));
+ eina_stringshare_del(ts->id);
+ eina_stringshare_del(ts->domain);
+ eina_stringshare_del(ts->string);
+ ELM_SAFE_FREE(ts, free);
}
+
+ *translate_strings = t;
+
+ return ts;
}
-static void
-_focused_object_clear(Elm_Widget_Smart_Data *sd)
+/* internal */
+void
+elm_widget_part_translatable_text_set(Eo *obj, const char *part, const char *label, const char *domain)
{
- if (sd->resize_obj && elm_widget_is(sd->resize_obj) &&
- _is_focused(sd->resize_obj))
+ Elm_Translate_String_Data *ts;
+ Elm_Widget_Smart_Data *sd;
+
+ sd = efl_data_scope_safe_get(obj, MY_CLASS);
+ if (!sd) return;
+
+ if (!label)
{
- efl_ui_widget_focused_object_clear(sd->resize_obj);
+ _part_text_translatable_set(&sd->translate_strings, part, EINA_FALSE,
+ EINA_FALSE);
}
else
{
- const Eina_List *l;
- Evas_Object *child;
- EINA_LIST_FOREACH(sd->subobjs, l, child)
- {
- if (_elm_widget_is(child) && _is_focused(child))
- {
- efl_ui_widget_focused_object_clear(child);
- break;
- }
- }
+ ts = _part_text_translatable_set(&sd->translate_strings, part,
+ EINA_TRUE, EINA_FALSE);
+ if (!ts) return;
+ if (!ts->string) ts->string = eina_stringshare_add(label);
+ else eina_stringshare_replace(&ts->string, label);
+ if (!ts->domain) ts->domain = eina_stringshare_add(domain);
+ else eina_stringshare_replace(&ts->domain, domain);
+#ifdef HAVE_GETTEXT
+ if (label[0]) label = dgettext(domain, label);
+#endif
}
-}
-EOLIAN static void
-_efl_ui_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)
- efl_ui_focus_object_on_focus_update(obj);
+ sd->on_translate = EINA_TRUE;
+ elm_widget_part_text_set(obj, part, label);
+ sd->on_translate = EINA_FALSE;
}
-EOLIAN static void
-_efl_ui_widget_focus_steal(Eo *obj, Elm_Widget_Smart_Data *sd, Elm_Object_Item *item)
-{
- Evas_Object *parent, *parent2, *o;
+/* legacy only */
+EAPI void
+elm_widget_domain_part_text_translatable_set(Eo *obj, const char *part, const char *domain, Eina_Bool translatable)
+{
+ Elm_Translate_String_Data *ts;
+ Elm_Widget_Smart_Data *sd;
+ const char *text = NULL;
- 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)))
- efl_ui_widget_focused_object_clear(parent);
- else
- {
- parent2 = elm_widget_parent_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;
-}
+ sd = efl_data_scope_safe_get(obj, MY_CLASS);
+ if (!sd) return;
-static void
-_parents_on_focus(Evas_Object *obj)
-{
- API_ENTRY return;
- if (!sd->focused || !sd->top_win_focused) return;
+ ts = _part_text_translatable_set(&sd->translate_strings, part,
+ translatable, EINA_TRUE);
+ if (!ts) return;
+ if (!ts->domain) ts->domain = eina_stringshare_add(domain);
+ else eina_stringshare_replace(&ts->domain, domain);
- Evas_Object *o = elm_widget_parent_get(obj);
- if (o) _parents_on_focus(o);
- efl_ui_focus_object_on_focus_update(obj);
+ text = elm_widget_part_text_get(obj, part);
+ if (!text || !text[0]) return;
+
+ if (!ts->string) ts->string = eina_stringshare_add(text);
+
+//Try to translate text since we don't know the text is already translated.
+#ifdef HAVE_GETTEXT
+ text = dgettext(domain, text);
+#endif
+ sd->on_translate = EINA_TRUE;
+ elm_widget_part_text_set(obj, part, text);
+ sd->on_translate = EINA_FALSE;
}
-EOLIAN static void
-_efl_ui_widget_focus_restore(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
+/* internal */
+const char *
+elm_widget_part_translatable_text_get(const Eo *obj, const char *part, const char **domain)
{
- Evas_Object *newest = NULL;
- unsigned int newest_focus_order = 0;
+ Elm_Widget_Smart_Data *sd;
+ Elm_Translate_String_Data *ts;
- newest = efl_ui_widget_newest_focus_order_get(obj, &newest_focus_order, EINA_TRUE);
- if (newest)
- _parents_on_focus(newest);
+ if (domain) *domain = NULL;
+
+ sd = efl_data_scope_safe_get(obj, MY_CLASS);
+ if (!sd) return NULL;
+
+ ts = _translate_string_data_get(sd->translate_strings, part);
+ if (!ts) return NULL;
+
+ if (domain) *domain = ts->domain;
+ return ts->string;
}
-//END
-/** @internal */
-EAPI void
-elm_widget_parent_highlight_set(Eo *obj, Eina_Bool highlighted)
+EOLIAN static void
+_efl_ui_widget_efl_ui_l10n_translation_update(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
{
- Elm_Widget_Smart_Data *sd =efl_data_scope_safe_get(obj, MY_CLASS);
- if (!sd) return;
-
- highlighted = !!highlighted;
+ const Eina_List *l;
+ Evas_Object *child;
- Evas_Object *o = elm_widget_parent_get(obj);
+ EINA_LIST_FOREACH(sd->subobjs, l, child)
+ {
+ if (elm_widget_is(child))
+ efl_ui_l10n_translation_update(child);
+ }
- if (o) elm_widget_parent_highlight_set(o, highlighted);
+ if (sd->hover_obj) efl_ui_l10n_translation_update(sd->hover_obj);
- sd->highlighted = highlighted;
+#ifdef HAVE_GETTEXT
+ Elm_Translate_String_Data *ts;
+ EINA_INLIST_FOREACH(sd->translate_strings, ts)
+ {
+ if (!ts->string) continue;
+ const char *s = dgettext(ts->domain, ts->string);
+ sd->on_translate = EINA_TRUE;
+ elm_widget_part_text_set(obj, ts->id, s);
+ sd->on_translate = EINA_FALSE;
+ }
+#endif
+ efl_event_callback_legacy_call(obj, EFL_UI_WIDGET_EVENT_LANGUAGE_CHANGED, NULL);
}
-EOLIAN static Evas_Object*
-_efl_ui_widget_widget_parent_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
+EOLIAN static void
+_efl_ui_widget_access_info_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, const char *txt)
{
- return sd->parent_obj;
+ eina_stringshare_replace(&sd->access_info, txt);
}
-void
-_elm_widget_focus_auto_show(Evas_Object *obj)
+EOLIAN static const char*
+_efl_ui_widget_access_info_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
{
- Evas_Object *top = elm_widget_top_get(obj);
- if (top && efl_isa(top, EFL_UI_WIN_CLASS)) _elm_win_focus_auto_show(top);
+ return sd->access_info;
}
-void
-_elm_widget_top_win_focused_set(Evas_Object *obj,
- Eina_Bool top_win_focused)
+//TIZEN_ONLY(20160822): When atspi mode is dynamically switched on/off,
+//register/unregister access objects accordingly.
+EAPI Eina_Bool
+elm_widget_screen_reader(Evas_Object *obj,
+ Eina_Bool is_screen_reader)
{
const Eina_List *l;
Evas_Object *child;
- API_ENTRY return;
+ Eina_Bool ret = EINA_TRUE;
- if (sd->top_win_focused == top_win_focused) return;
+ API_ENTRY return EINA_FALSE;
EINA_LIST_FOREACH(sd->subobjs, l, child)
{
if (elm_widget_is(child))
- _elm_widget_top_win_focused_set(child, top_win_focused);
+ ret &= elm_widget_screen_reader(child, is_screen_reader);
}
- sd->top_win_focused = top_win_focused;
+ efl_ui_widget_screen_reader(obj, is_screen_reader);
- if (sd->focused && !sd->top_win_focused)
- efl_ui_focus_object_on_focus_update(obj);
+ return ret;
}
-Eina_Bool
-_elm_widget_top_win_focused_get(const Evas_Object *obj)
+EOLIAN static void
+_efl_ui_widget_screen_reader(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED, Eina_Bool is_screen_reader EINA_UNUSED)
{
- API_ENTRY return EINA_FALSE;
- return sd->top_win_focused;
}
+//
-static void
-_elm_widget_disabled_eval(const Evas_Object *obj, Eina_Bool disabled)
+//TIZEN_ONLY(20170621) handle atspi proxy connection at runtime
+EAPI Eina_Bool
+elm_widget_atspi(Evas_Object *obj, Eina_Bool is_atspi)
{
- const Eina_List *l;
+ Eina_List *l, *children;
Evas_Object *child;
- ELM_WIDGET_DATA_GET(obj, sd);
+ Eina_Bool ret = EINA_TRUE;
- EINA_LIST_FOREACH(sd->subobjs, l, child)
+ API_ENTRY return EINA_FALSE;
+ children = efl_access_object_access_children_get(obj);
+ EINA_LIST_FOREACH(children, l, child)
{
- if (elm_widget_is(child))
- {
- //TIZEN_ONLY(20180607): Restore legacy focus
- if (elm_widget_is_legacy(obj))
- efl_ui_widget_focus_disabled_handle((Evas_Object *)obj);
- //
- efl_ui_widget_on_disabled_update(child, disabled);
- _elm_widget_disabled_eval(child, disabled);
- }
+ ret &= elm_widget_atspi(child, is_atspi);
}
-}
+ efl_ui_widget_atspi(obj, is_atspi);
-static void
-elm_widget_disabled_internal(Eo *obj, Eina_Bool disabled)
-{
- if (!disabled && elm_widget_disabled_get(elm_widget_parent_get(obj)))
- return;
- //TIZEN_ONLY(20180607): Restore legacy focus
- if (elm_widget_is_legacy(obj))
- efl_ui_widget_focus_disabled_handle(obj);
- //
- efl_ui_widget_on_disabled_update(obj, disabled);
- _elm_widget_disabled_eval(obj, disabled);
+ return ret;
}
EOLIAN static void
-_efl_ui_widget_disabled_set(Eo *obj, Elm_Widget_Smart_Data *sd, Eina_Bool disabled)
+_efl_ui_widget_atspi(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED, Eina_Bool is_atspi EINA_UNUSED)
{
- if (sd->disabled == disabled) return;
- sd->disabled = !!disabled;
-
- elm_widget_disabled_internal(obj, disabled);
-
- if (efl_finalized_get(obj))
- _elm_widget_full_eval_children(obj, sd);
}
+//
+//
-EOLIAN static Eina_Bool
-_efl_ui_widget_disabled_get(const Eo *obj, Elm_Widget_Smart_Data *sd)
+EAPI Elm_Theme *
+elm_widget_theme_get(const Evas_Object *obj)
{
- Eo *parent;
+ Elm_Widget_Smart_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
+ if (!sd) return NULL;
- if (sd->disabled) return EINA_TRUE;
- if ((parent = elm_widget_parent_get(obj)) != NULL)
- return elm_widget_disabled_get(parent);
- return EINA_FALSE;
+ if (!sd->theme)
+ {
+ if (sd->parent_obj && elm_widget_is(sd->parent_obj))
+ return elm_widget_theme_get(sd->parent_obj);
+ else return NULL;
+ }
+ return sd->theme;
}
-EOLIAN static void
-_efl_ui_widget_show_region_set(Eo *obj, Elm_Widget_Smart_Data *sd, Eina_Rect sr, Eina_Bool forceshow)
+EOLIAN static Efl_Ui_Theme_Apply_Result
+_efl_ui_widget_style_set(Eo *obj, Elm_Widget_Smart_Data *sd, const char *style)
{
- Evas_Object *parent_obj, *child_obj;
- Evas_Coord px, py, cx, cy, nx = 0, ny = 0;
+ if (!elm_widget_is_legacy(obj) && efl_finalized_get(obj))
+ {
+ ERR("Efl.Ui.Widget.style can only be set before finalize!");
+ return EFL_UI_THEME_APPLY_RESULT_FAIL;
+ }
- /*****************************************************************************
- * TIZEN_ONLY_FEATURE: Fix entry size/cursor/region calculation for Tizen UX *
- *****************************************************************************
- * Move this code to the below to update show region geometry properly.
- evas_smart_objects_calculate(evas_object_evas_get(obj));
- */
- /*******
- * END *
- *******/
+ if (eina_stringshare_replace(&sd->style, style))
+ return elm_widget_theme(obj);
- if (!forceshow && eina_rectangle_equal(&sr.rect, &sd->show_region.rect)) return;
+ return EFL_UI_THEME_APPLY_RESULT_SUCCESS;
+}
- sd->show_region = sr;
+EOLIAN static const char*
+_efl_ui_widget_style_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
+{
+ const char *ret;
+ ret = "default";
+ if (sd->style) ret = sd->style;
- /*****************************************************************************
- * TIZEN_ONLY_FEATURE: Fix entry size/cursor/region calculation for Tizen UX *
- *****************************************************************************/
- /* Block nested call for evas_smart_objects_calculate() and region showing works */
- if (sd->on_show_region_set) return;
-
- sd->on_show_region_set = EINA_TRUE;
-
- evas_smart_objects_calculate(evas_object_evas_get(obj));
-
- sd->on_show_region_set = EINA_FALSE;
-
- /* show_region geometry could be changed during processing elm_widget_show_region_set().
- evas_smart_objects_calculate() can trigger nested show_region_set calls */
- sr = sd->show_region;
- /*******
- * END *
- *******/
-
- if (sd->on_show_region)
- {
- sd->on_show_region(sd->on_show_region_data, obj, sr);
-
- if (_elm_scrollable_is(obj))
- {
- if (elm_widget_is_legacy(obj))
- {
- elm_interface_scrollable_content_pos_get(obj, &nx, &ny);
- sr.x -= nx;
- sr.y -= ny;
- }
- else
- {
- Eina_Position2D pos;
- pos = efl_ui_scrollable_content_pos_get(obj);
- sr.x -= pos.x;
- sr.y -= pos.y;
- }
- }
- }
+ return ret;
+}
- do
- {
- parent_obj = sd->parent_obj;
- child_obj = sd->obj;
- if ((!parent_obj) || (!_elm_widget_is(parent_obj))) break;
- sd = efl_data_scope_get(parent_obj, MY_CLASS);
- if (!sd) break;
+EAPI void
+elm_widget_tooltip_add(Eo *obj, Elm_Tooltip *tt)
+{
+ Elm_Widget_Smart_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
+ if (!sd) return;
- evas_object_geometry_get(parent_obj, &px, &py, NULL, NULL);
- evas_object_geometry_get(child_obj, &cx, &cy, NULL, NULL);
+ sd->tooltips = eina_list_append(sd->tooltips, tt);
+}
- sr.x += (cx - px);
- sr.y += (cy - py);
- sd->show_region = sr;
+EAPI void
+elm_widget_tooltip_del(Eo *obj, Elm_Tooltip *tt)
+{
+ Elm_Widget_Smart_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
+ if (!sd) return;
- if (sd->on_show_region)
- sd->on_show_region(sd->on_show_region_data, parent_obj, sr);
- }
- while (parent_obj);
+ sd->tooltips = eina_list_remove(sd->tooltips, tt);
}
-EOLIAN static Eina_Rect
-_efl_ui_widget_show_region_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
+EAPI void
+elm_widget_cursor_add(Eo *obj, Elm_Cursor *cur)
{
- return (Eina_Rect) sd->show_region;
+ Elm_Widget_Smart_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
+ if (!sd) return;
+
+ sd->cursors = eina_list_append(sd->cursors, cur);
}
-/**
- * @internal
- *
- * Get the focus region of the given widget.
- *
- * @return The region to show. If it's not a valid rectangle it will not show.
- *
- * The focus region is the area of a widget that should brought into the
- * visible area when the widget is focused. Mostly used to show the part of
- * an entry where the cursor is, for example. The area returned is relative
- * to the object @p obj.
- *
- * @param obj The widget object
- * @return The region to show, in relative coordinates. If it's not a valid
- * rectangle (i.e. w or h <= 0) it will be ignored.
- *
- * @ingroup Widget
- */
-EOLIAN static Eina_Rect
-_efl_ui_widget_interest_region_get(const Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
+EAPI void
+elm_widget_cursor_del(Eo *obj, Elm_Cursor *cur)
{
- Eina_Rect r = {};
- r.size = efl_gfx_entity_size_get(obj);
- return r;
+ Elm_Widget_Smart_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
+ if (!sd) return;
+
+ sd->cursors = eina_list_remove(sd->cursors, cur);
}
-EOLIAN static void
-_efl_ui_widget_scroll_hold_push(Eo *obj, Elm_Widget_Smart_Data *sd)
+EAPI void
+elm_widget_scroll_lock_set(Eo *obj, Efl_Ui_Scroll_Block block)
{
- sd->scroll_hold++;
- if (sd->scroll_hold == 1)
- {
- if (_elm_scrollable_is(obj))
- {
- if (elm_widget_is_legacy(obj))
- elm_interface_scrollable_hold_set(obj, EINA_TRUE);
- else
- efl_ui_scrollable_scroll_hold_set(obj, EINA_TRUE);
- }
- else
- {
- Evas_Object *child;
- Eina_List *l;
+ Elm_Widget_Smart_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
+ Eina_Bool lx, ly;
- EINA_LIST_FOREACH(sd->subobjs, l, child)
- {
- if (elm_widget_is(child) && _elm_scrollable_is(child))
- {
- if (elm_widget_is_legacy(obj))
- elm_interface_scrollable_hold_set(child, EINA_TRUE);
- else
- efl_ui_scrollable_scroll_hold_set(child, EINA_TRUE);
- }
- }
- }
+ if (!sd) return;
+ lx = !!(block & EFL_UI_SCROLL_BLOCK_HORIZONTAL);
+ ly = !!(block & EFL_UI_SCROLL_BLOCK_VERTICAL);
+ if (sd->scroll_x_locked != lx)
+ {
+ sd->scroll_x_locked = lx;
+ _propagate_x_drag_lock(obj, lx ? 1 : -1);
+ }
+ if (sd->scroll_y_locked != ly)
+ {
+ sd->scroll_y_locked = ly;
+ _propagate_y_drag_lock(obj, ly ? 1 : -1);
}
- if (sd->parent_obj) efl_ui_widget_scroll_hold_push(sd->parent_obj);
- // FIXME: on delete/reparent hold pop
}
-EOLIAN static void
-_efl_ui_widget_scroll_hold_pop(Eo *obj, Elm_Widget_Smart_Data *sd)
+EAPI Efl_Ui_Scroll_Block
+elm_widget_scroll_lock_get(const Eo *obj)
{
- sd->scroll_hold--;
- if (!sd->scroll_hold)
- {
- if (_elm_scrollable_is(obj))
- {
- if (elm_widget_is_legacy(obj))
- elm_interface_scrollable_hold_set(obj, EINA_FALSE);
- else
- efl_ui_scrollable_scroll_hold_set(obj, EINA_FALSE);
- }
- else
- {
- Evas_Object *child;
- Eina_List *l;
+ Elm_Widget_Smart_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
+ Efl_Ui_Scroll_Block block = EFL_UI_SCROLL_BLOCK_NONE;
- EINA_LIST_FOREACH(sd->subobjs, l, child)
- {
- if (elm_widget_is(child) && _elm_scrollable_is(child))
- {
- if (elm_widget_is_legacy(obj))
- elm_interface_scrollable_hold_set(child, EINA_FALSE);
- else
- efl_ui_scrollable_scroll_hold_set(child, EINA_FALSE);
- }
- }
- }
- }
- if (sd->parent_obj) efl_ui_widget_scroll_hold_pop(sd->parent_obj);
- if (sd->scroll_hold < 0) sd->scroll_hold = 0;
+ if (!sd) return block;
+ if (sd->scroll_x_locked) block |= EFL_UI_SCROLL_BLOCK_HORIZONTAL;
+ if (sd->scroll_y_locked) block |= EFL_UI_SCROLL_BLOCK_VERTICAL;
+
+ return block;
}
EAPI int
-elm_widget_scroll_hold_get(const Eo *obj)
+elm_widget_scroll_child_locked_x_get(const Eo *obj)
{
Elm_Widget_Smart_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
+ if (!sd) return EINA_FALSE;
+ return sd->child_drag_x_locked;
+}
- if (!sd) return 0;
- return sd->scroll_hold;
+EAPI int
+elm_widget_scroll_child_locked_y_get(const Eo *obj)
+{
+ Elm_Widget_Smart_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
+ if (!sd) return EINA_FALSE;
+ return sd->child_drag_y_locked;
}
-EOLIAN static void
-_efl_ui_widget_scroll_freeze_push(Eo *obj, Elm_Widget_Smart_Data *sd)
+EAPI Efl_Ui_Theme_Apply_Result
+elm_widget_theme_object_set(Evas_Object *obj, Evas_Object *edj, const char *wname, const char *welement, const char *wstyle)
{
- sd->scroll_freeze++;
- if (sd->scroll_freeze == 1)
+ Elm_Widget_Smart_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
+ if (!sd) return EFL_UI_THEME_APPLY_RESULT_FAIL;
+
+ if (eina_streq(welement, "base"))
+ welement = NULL;
+ if (eina_streq(wstyle, "default"))
+ wstyle = NULL;
+ Efl_Ui_Theme_Apply_Result ret = _elm_theme_object_set(obj, edj, wname, welement, wstyle);
+ if (!ret)
{
- if (_elm_scrollable_is(obj))
+ return EFL_UI_THEME_APPLY_RESULT_FAIL;
+ }
+
+ if (sd->orient_mode != -1)
+ {
+ char buf[128];
+
+ if (elm_widget_is_legacy(obj))
{
- if (elm_widget_is_legacy(obj))
- elm_interface_scrollable_freeze_set(obj, EINA_TRUE);
- else
- efl_ui_scrollable_scroll_freeze_set(obj, EINA_TRUE);
+ snprintf(buf, sizeof(buf), "elm,state,orient,%d", sd->orient_mode);
+ elm_widget_signal_emit(obj, buf, "elm");
}
else
{
- Evas_Object *child;
- Eina_List *l;
-
- EINA_LIST_FOREACH(sd->subobjs, l, child)
- {
- if (elm_widget_is(child) && _elm_scrollable_is(child))
- if (elm_widget_is_legacy(obj))
- elm_interface_scrollable_freeze_set(child, EINA_TRUE);
- else
- efl_ui_scrollable_scroll_freeze_set(child, EINA_TRUE);
- }
+ snprintf(buf, sizeof(buf), "efl,state,orient,%d", sd->orient_mode);
+ elm_widget_signal_emit(obj, buf, "efl");
}
}
- if (sd->parent_obj) efl_ui_widget_scroll_freeze_push(sd->parent_obj);
- // FIXME: on delete/reparent freeze pop
+
+ return ret;
}
-EOLIAN static void
-_efl_ui_widget_scroll_freeze_pop(Eo *obj, Elm_Widget_Smart_Data *sd)
+static void
+_convert(Efl_Dbg_Info *info, Eina_Iterator *ptr_list)
{
- sd->scroll_freeze--;
- if (!sd->scroll_freeze)
+ void *p;
+ int i = 0;
+
+ EINA_ITERATOR_FOREACH(ptr_list, p)
{
- if (_elm_scrollable_is(obj))
- {
- if (elm_widget_is_legacy(obj))
- elm_interface_scrollable_freeze_set(obj, EINA_FALSE);
- else
- efl_ui_scrollable_scroll_freeze_set(obj, EINA_FALSE);
- }
- else
- {
- Evas_Object *child;
- Eina_List *l;
+ char name[100];
- EINA_LIST_FOREACH(sd->subobjs, l, child)
- {
- if (elm_widget_is(child) && _elm_scrollable_is(child))
- if (elm_widget_is_legacy(obj))
- elm_interface_scrollable_freeze_set(child, EINA_FALSE);
- else
- efl_ui_scrollable_scroll_freeze_set(child, EINA_FALSE);
- }
- }
+ snprintf(name, sizeof(name), "Candidate %d", i);
+
+ EFL_DBG_INFO_APPEND(info, name, EINA_VALUE_TYPE_UINT64, p);
+ i++;
}
- if (sd->parent_obj) efl_ui_widget_scroll_freeze_pop(sd->parent_obj);
- if (sd->scroll_freeze < 0) sd->scroll_freeze = 0;
+
+ eina_iterator_free(ptr_list);
}
-EAPI int
-elm_widget_scroll_freeze_get(const Eo *obj)
+EOLIAN static void
+_efl_ui_widget_efl_object_dbg_info_get(Eo *eo_obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED, Efl_Dbg_Info *root)
{
- Elm_Widget_Smart_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
+ efl_dbg_info_get(efl_super(eo_obj, MY_CLASS), root);
+ Efl_Ui_Focus_Relations *rel = NULL;
+ Efl_Dbg_Info *focus, *group = EFL_DBG_INFO_LIST_APPEND(root, MY_CLASS_NAME);
- if (!sd) return 0;
- return sd->scroll_freeze;
-}
+ EFL_DBG_INFO_APPEND(group, "Wid-Type", EINA_VALUE_TYPE_STRING, elm_widget_type_get(eo_obj));
+ EFL_DBG_INFO_APPEND(group, "Style", EINA_VALUE_TYPE_STRING, elm_widget_style_get(eo_obj));
+ EFL_DBG_INFO_APPEND(group, "Layer", EINA_VALUE_TYPE_INT,
+ (int) evas_object_layer_get(eo_obj));
+ EFL_DBG_INFO_APPEND(group, "Scale", EINA_VALUE_TYPE_DOUBLE,
+ evas_object_scale_get(eo_obj));
+ EFL_DBG_INFO_APPEND(group, "Has focus", EINA_VALUE_TYPE_CHAR,
+ elm_object_focus_get(eo_obj));
+ EFL_DBG_INFO_APPEND(group, "Can focus", EINA_VALUE_TYPE_CHAR,
+ elm_widget_can_focus_get(eo_obj));
+ EFL_DBG_INFO_APPEND(group, "Disabled", EINA_VALUE_TYPE_CHAR,
+ elm_widget_disabled_get(eo_obj));
+ EFL_DBG_INFO_APPEND(group, "Mirrored", EINA_VALUE_TYPE_CHAR,
+ efl_ui_mirrored_get(eo_obj));
+ EFL_DBG_INFO_APPEND(group, "Tree Unfocusable", EINA_VALUE_TYPE_CHAR,
+ elm_widget_tree_unfocusable_get(eo_obj));
+ EFL_DBG_INFO_APPEND(group, "Automatic mirroring", EINA_VALUE_TYPE_CHAR,
+ efl_ui_mirrored_automatic_get(eo_obj));
-// TIZEN_ONLY(20150705): Genlist item align feature
-EAPI void
-elm_widget_scroll_item_align_enabled_set(Evas_Object *obj,
- Eina_Bool scroll_item_align_enable)
-{
- API_ENTRY return;
- if (sd->scroll_item_align_enable == scroll_item_align_enable) return;
- sd->scroll_item_align_enable = scroll_item_align_enable;
-}
+ rel = efl_ui_focus_manager_fetch(_pd->focus.manager, eo_obj);
+ if (rel)
+ {
+ focus = EFL_DBG_INFO_LIST_APPEND(group, "Focus");
-EAPI Eina_Bool
-elm_widget_scroll_item_align_enabled_get(const Evas_Object *obj)
-{
- API_ENTRY return EINA_FALSE;
- return sd->scroll_item_align_enable;
-}
+ EFL_DBG_INFO_APPEND(focus, "logical", EINA_VALUE_TYPE_CHAR, rel->logical );
+ EFL_DBG_INFO_APPEND(focus, "manager", EINA_VALUE_TYPE_UINT64, _pd->focus.manager);
+ EFL_DBG_INFO_APPEND(focus, "parent", EINA_VALUE_TYPE_UINT64, rel->parent);
+ EFL_DBG_INFO_APPEND(focus, "next", EINA_VALUE_TYPE_UINT64 , rel->next);
+ EFL_DBG_INFO_APPEND(focus, "prev", EINA_VALUE_TYPE_UINT64 , rel->prev);
-EAPI void
-elm_widget_scroll_item_valign_set(Evas_Object *obj,
- const char *scroll_item_valign)
-{
- API_ENTRY return;
- if (sd->scroll_item_valign) eina_stringshare_del(sd->scroll_item_valign);
- if (!scroll_item_valign) sd->scroll_item_valign = NULL;
- else sd->scroll_item_valign = eina_stringshare_add(scroll_item_valign);
-}
+ EFL_DBG_INFO_APPEND(focus, "redirect", EINA_VALUE_TYPE_UINT64 , rel->redirect);
-EAPI const char*
-elm_widget_scroll_item_valign_get(const Evas_Object *obj)
-{
- API_ENTRY return NULL;
- return sd->scroll_item_valign;
-}
-//
+#define ADD_PTR_LIST(name) \
+ Efl_Dbg_Info* name = EFL_DBG_INFO_LIST_APPEND(focus, ""#name""); \
+ _convert(name, eina_list_iterator_new(rel->name));
+
+ ADD_PTR_LIST(top)
+ ADD_PTR_LIST(down)
+ ADD_PTR_LIST(right)
+ ADD_PTR_LIST(left)
+
+#undef ADD_PTR_LIST
-EOLIAN static void
-_efl_ui_widget_efl_gfx_entity_scale_set(Eo *obj, Elm_Widget_Smart_Data *sd, double scale)
-{
- if (scale < 0.0) scale = 0.0;
- if (sd->scale != scale)
- {
- sd->scale = scale;
- elm_widget_theme(obj);
}
-}
-EOLIAN static double
-_efl_ui_widget_efl_gfx_entity_scale_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
-{
- // FIXME: save walking up the tree by storing/caching parent scale
- if (sd->scale == 0.0)
+ //if thats a focus manager, give useful information like the border elements
+ if (efl_isa(eo_obj, EFL_UI_FOCUS_MANAGER_INTERFACE))
{
- if (sd->parent_obj && elm_widget_is(sd->parent_obj))
- {
- return efl_gfx_entity_scale_get(sd->parent_obj);
- }
- else
- {
- return 1.0;
- }
+ Efl_Dbg_Info *border;
+
+ focus = EFL_DBG_INFO_LIST_APPEND(group, "Focus Manager");
+ border = EFL_DBG_INFO_LIST_APPEND(focus, "Border Elements");
+
+ _convert(border,
+ efl_ui_focus_manager_border_elements_get(eo_obj)
+ );
+
+ EFL_DBG_INFO_APPEND(focus, "redirect", EINA_VALUE_TYPE_UINT64,
+ efl_ui_focus_manager_redirect_get(eo_obj));
}
- return sd->scale;
}
-EAPI void
-elm_widget_theme_set(Evas_Object *obj, Elm_Theme *th)
+EAPI Eina_Bool
+elm_widget_is_check(const Evas_Object *obj)
{
- Elm_Widget_Smart_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
- if (!sd) return;
+ static int abort_on_warn = -1;
+ if (elm_widget_is(obj))
+ return EINA_TRUE;
- Eina_Bool apply = EINA_FALSE;
- if (sd->theme != th)
+ ERR("Passing Object: %p.", obj);
+ if (abort_on_warn == -1)
{
- if (elm_widget_theme_get(obj) != th) apply = EINA_TRUE;
- if (sd->theme) elm_theme_free(sd->theme);
- sd->theme = th;
- if (th) efl_ref(th->eo_theme);
- if (apply) elm_widget_theme(obj);
+ if (getenv("ELM_ERROR_ABORT")) abort_on_warn = 1;
+ else abort_on_warn = 0;
}
+ if (abort_on_warn == 1) abort();
+ return EINA_FALSE;
}
-EAPI void
-elm_widget_part_text_set(Eo *obj, const char *part, const char *label)
-{
- /* legacy support: combobox was special (internal entry is text object). */
- //TIZEN_ONLY(20180426):stop creating unused class.
- if (efl_isa(obj, EFL_UI_LAYOUT_CLASS))
- elm_layout_text_set(obj, part, label);
- else if (efl_isa(obj, ELM_COMBOBOX_CLASS))
- _elm_combobox_part_text_set(obj, part, label);
- //
-}
-
-EAPI const char*
-elm_widget_part_text_get(const Eo *obj, const char *part)
+/* If you changed a legacy widget's class name,
+ * please update the "legacy_type_table". */
+EAPI const char *
+elm_widget_type_get(const Evas_Object *obj)
{
- /* legacy support: combobox was special (internal entry is text object). */
- //TIZEN_ONLY(20180426):stop creating unused class.
- if (efl_isa(obj, EFL_UI_LAYOUT_CLASS))
- return elm_layout_text_get(obj, part);
- else if (efl_isa(obj, ELM_COMBOBOX_CLASS))
- return _elm_combobox_part_text_get(obj, part);
- //
-
- return NULL;
-}
+ const char *ret;
+ int i;
-static Elm_Translate_String_Data *
-_translate_string_data_get(Eina_Inlist *translate_strings, const char *part)
-{
- Elm_Translate_String_Data *ts;
- Eina_Stringshare *str;
+ API_ENTRY return NULL;
- if (!translate_strings) return NULL;
+ ret = efl_class_name_get(efl_class_get(obj));
- str = eina_stringshare_add(part);
- EINA_INLIST_FOREACH(translate_strings, ts)
+ /* If the given widget is created for legacy,
+ * convert type name to legacy. */
+ if (elm_widget_is_legacy(obj))
{
- if (ts->id == str) break;
+ for (i = 0; legacy_type_table[i][0] ; i++)
+ {
+ if (eina_streq(ret, legacy_type_table[i][0]))
+ return legacy_type_table[i][1];
+ }
}
- eina_stringshare_del(str);
-
- return ts;
+ return ret;
}
-static Elm_Translate_String_Data *
-_part_text_translatable_set(Eina_Inlist **translate_strings, const char *part, Eina_Bool translatable, Eina_Bool preset)
+EAPI Eina_Bool
+elm_widget_type_check(const Evas_Object *obj,
+ const char *type,
+ const char *func)
{
- Eina_Inlist *t;
- Elm_Translate_String_Data *ts;
- t = *translate_strings;
- ts = _translate_string_data_get(t, part);
+ const char *provided, *expected = "(unknown)";
+ static int abort_on_warn = -1;
- if (translatable)
+ provided = elm_widget_type_get(obj);
+ /* TODO: eventually migrate to check_ptr version */
+ if (evas_object_smart_type_check(obj, type)) return EINA_TRUE;
+ if (type) expected = type;
+ if ((!provided) || (!provided[0]))
{
- if (!ts)
- {
- ts = ELM_NEW(Elm_Translate_String_Data);
- if (!ts) return NULL;
-
- ts->id = eina_stringshare_add(part);
- t = eina_inlist_append(t, (Eina_Inlist*) ts);
- }
- if (preset) ts->preset = EINA_TRUE;
+ provided = evas_object_type_get(obj);
+ if ((!provided) || (!provided[0]))
+ provided = "(unknown)";
}
- //Delete this exist one if this part has been not preset.
- //see elm_widget_part_text_translatable_set()
- else if (ts && ((preset) || (!ts->preset)))
- {
- t = eina_inlist_remove(t, EINA_INLIST_GET(ts));
- eina_stringshare_del(ts->id);
- eina_stringshare_del(ts->domain);
- eina_stringshare_del(ts->string);
- ELM_SAFE_FREE(ts, free);
- }
-
- *translate_strings = t;
-
- return ts;
-}
-
-/* internal */
-void
-elm_widget_part_translatable_text_set(Eo *obj, const char *part, const char *label, const char *domain)
-{
- Elm_Translate_String_Data *ts;
- Elm_Widget_Smart_Data *sd;
-
- sd = efl_data_scope_safe_get(obj, MY_CLASS);
- if (!sd) return;
-
- if (!label)
- {
- _part_text_translatable_set(&sd->translate_strings, part, EINA_FALSE,
- EINA_FALSE);
- }
- else
+ ERR("Passing Object: %p in function: %s, of type: '%s' when expecting"
+ " type: '%s'", obj, func, provided, expected);
+ if (abort_on_warn == -1)
{
- ts = _part_text_translatable_set(&sd->translate_strings, part,
- EINA_TRUE, EINA_FALSE);
- if (!ts) return;
- if (!ts->string) ts->string = eina_stringshare_add(label);
- else eina_stringshare_replace(&ts->string, label);
- if (!ts->domain) ts->domain = eina_stringshare_add(domain);
- else eina_stringshare_replace(&ts->domain, domain);
-#ifdef HAVE_GETTEXT
- if (label[0]) label = dgettext(domain, label);
-#endif
+ if (getenv("ELM_ERROR_ABORT")) abort_on_warn = 1;
+ else abort_on_warn = 0;
}
-
- sd->on_translate = EINA_TRUE;
- elm_widget_part_text_set(obj, part, label);
- sd->on_translate = EINA_FALSE;
-}
-
-/* legacy only */
-EAPI void
-elm_widget_domain_part_text_translatable_set(Eo *obj, const char *part, const char *domain, Eina_Bool translatable)
-{
- Elm_Translate_String_Data *ts;
- Elm_Widget_Smart_Data *sd;
- const char *text = NULL;
-
- sd = efl_data_scope_safe_get(obj, MY_CLASS);
- if (!sd) return;
-
- ts = _part_text_translatable_set(&sd->translate_strings, part,
- translatable, EINA_TRUE);
- if (!ts) return;
- if (!ts->domain) ts->domain = eina_stringshare_add(domain);
- else eina_stringshare_replace(&ts->domain, domain);
-
- text = elm_widget_part_text_get(obj, part);
- if (!text || !text[0]) return;
-
- if (!ts->string) ts->string = eina_stringshare_add(text);
-
-//Try to translate text since we don't know the text is already translated.
-#ifdef HAVE_GETTEXT
- text = dgettext(domain, text);
-#endif
- sd->on_translate = EINA_TRUE;
- elm_widget_part_text_set(obj, part, text);
- sd->on_translate = EINA_FALSE;
-}
-
-/* internal */
-const char *
-elm_widget_part_translatable_text_get(const Eo *obj, const char *part, const char **domain)
-{
- Elm_Widget_Smart_Data *sd;
- Elm_Translate_String_Data *ts;
-
- if (domain) *domain = NULL;
-
- sd = efl_data_scope_safe_get(obj, MY_CLASS);
- if (!sd) return NULL;
-
- ts = _translate_string_data_get(sd->translate_strings, part);
- if (!ts) return NULL;
-
- if (domain) *domain = ts->domain;
- return ts->string;
+ if (abort_on_warn == 1) abort();
+ return EINA_FALSE;
}
-EOLIAN static void
-_efl_ui_widget_efl_ui_l10n_translation_update(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
+/** @internal */
+EAPI Evas_Object *
+elm_widget_name_find(const Eo *obj, const char *name, int recurse)
{
- const Eina_List *l;
+ Eina_List *l;
Evas_Object *child;
+ const char *s;
+ INTERNAL_ENTRY NULL;
+ if (!name) return NULL;
+ if (!_elm_widget_is(obj)) return NULL;
EINA_LIST_FOREACH(sd->subobjs, l, child)
{
- if (elm_widget_is(child))
- efl_ui_l10n_translation_update(child);
+ s = evas_object_name_get(child);
+ if ((s) && (!strcmp(s, name))) return child;
+ if ((recurse != 0) &&
+ ((child = elm_widget_name_find(child, name, recurse - 1))))
+ return child;
}
-
- if (sd->hover_obj) efl_ui_l10n_translation_update(sd->hover_obj);
-
-#ifdef HAVE_GETTEXT
- Elm_Translate_String_Data *ts;
- EINA_INLIST_FOREACH(sd->translate_strings, ts)
+ if (sd->hover_obj)
{
- if (!ts->string) continue;
- const char *s = dgettext(ts->domain, ts->string);
- sd->on_translate = EINA_TRUE;
- elm_widget_part_text_set(obj, ts->id, s);
- sd->on_translate = EINA_FALSE;
+ s = evas_object_name_get(sd->hover_obj);
+ if ((s) && (!strcmp(s, name))) return sd->hover_obj;
+ if ((recurse != 0) &&
+ ((child = elm_widget_name_find(sd->hover_obj, name, recurse - 1))))
+ return child;
}
-#endif
- efl_event_callback_legacy_call(obj, EFL_UI_WIDGET_EVENT_LANGUAGE_CHANGED, NULL);
-}
-
-EOLIAN static void
-_efl_ui_widget_access_info_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, const char *txt)
-{
- eina_stringshare_replace(&sd->access_info, txt);
-}
-
-EOLIAN static const char*
-_efl_ui_widget_access_info_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
-{
- return sd->access_info;
+ return NULL;
}
-//TIZEN_ONLY(20160822): When atspi mode is dynamically switched on/off,
-//register/unregister access objects accordingly.
-EAPI Eina_Bool
-elm_widget_screen_reader(Evas_Object *obj,
- Eina_Bool is_screen_reader)
+/**
+ * @internal
+ *
+ * Split string in words
+ *
+ * @param str Source string
+ * @return List of const words
+ *
+ * @see elm_widget_stringlist_free()
+ * @ingroup Widget
+ */
+EAPI Eina_List *
+elm_widget_stringlist_get(const char *str)
{
- const Eina_List *l;
- Evas_Object *child;
- Eina_Bool ret = EINA_TRUE;
-
- API_ENTRY return EINA_FALSE;
- EINA_LIST_FOREACH(sd->subobjs, l, child)
+ Eina_List *list = NULL;
+ const char *s, *b;
+ if (!str) return NULL;
+ for (b = s = str; 1; s++)
{
- if (elm_widget_is(child))
- ret &= elm_widget_screen_reader(child, is_screen_reader);
+ if ((*s == ' ') || (!*s))
+ {
+ char *t = malloc(s - b + 1);
+ if (t)
+ {
+ strncpy(t, b, s - b);
+ t[s - b] = 0;
+ list = eina_list_append(list, eina_stringshare_add(t));
+ free(t);
+ }
+ b = s + 1;
+ }
+ if (!*s) break;
}
- efl_ui_widget_screen_reader(obj, is_screen_reader);
-
- return ret;
+ return list;
}
+EAPI void
+elm_widget_stringlist_free(Eina_List *list)
+{
+ const char *s;
+ EINA_LIST_FREE(list, s)
+ eina_stringshare_del(s);
+}
+//TIZEN_ONLY(20180607): Restore legacy focus
EOLIAN static void
-_efl_ui_widget_screen_reader(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED, Eina_Bool is_screen_reader EINA_UNUSED)
+_efl_ui_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);
}
//
-
-//TIZEN_ONLY(20170621) handle atspi proxy connection at runtime
-EAPI Eina_Bool
-elm_widget_atspi(Evas_Object *obj, Eina_Bool is_atspi)
+/* internal */
+EAPI void
+elm_widget_focus_mouse_up_handle(Eo *obj)
{
- Eina_List *l, *children;
- Evas_Object *child;
- Eina_Bool ret = EINA_TRUE;
+ Elm_Widget_Smart_Data *pd = efl_data_scope_get(obj, MY_CLASS);
- API_ENTRY return EINA_FALSE;
- children = efl_access_object_access_children_get(obj);
- EINA_LIST_FOREACH(children, l, child)
+ if (!_is_focusable(obj)) return;
+
+ //TIZEN_ONLY(20180607): Restore legacy focus
+ if (elm_widget_is_legacy(obj))
{
- ret &= elm_widget_atspi(child, is_atspi);
- }
- efl_ui_widget_atspi(obj, is_atspi);
+ Evas_Object *o = obj;
+ do
+ {
+ if (_elm_widget_is(o)) break;
+ o = evas_object_smart_parent_get(o);
+ }
+ while (o);
- return ret;
+ efl_ui_widget_focus_mouse_up_handle(o);
+ return;
+ }
+ //
+ if (pd->focus.manager && !pd->focus.logical)
+ {
+ efl_ui_focus_util_focus(obj);
+ }
}
EOLIAN static void
-_efl_ui_widget_atspi(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED, Eina_Bool is_atspi EINA_UNUSED)
+_efl_ui_widget_focus_tree_unfocusable_handle(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
{
+ if (!elm_widget_parent_get(obj))
+ efl_ui_widget_focused_object_clear(obj);
+ else
+ _if_focused_revert(obj, EINA_TRUE);
}
-//
-//
-EAPI Elm_Theme *
-elm_widget_theme_get(const Evas_Object *obj)
+/*
+ * @internal
+ *
+ * Get the focus highlight geometry of a widget.
+ *
+ * @param obj Widget object for the focus highlight
+ * @param x Focus highlight x coordinate
+ * @param y Focus highlight y coordinate
+ * @param w Focus highlight object width
+ * @param h Focus highlight object height
+ * @param is_next @c EINA_TRUE if this request is for the new focused object,
+ * @c EINA_FALSE if this request is for the previously focused object. This
+ * information becomes important when the focus highlight is changed inside one
+ * widget.
+ *
+ * @ingroup Widget
+ */
+/*
+ * @internal
+ *
+ * Get the 'focus_part' geometry if there is any
+ *
+ * This queries if there is a 'focus_part' request from the edc style. If edc
+ * style offers 'focus_part' edje data item, this function requests for the
+ * geometry of a specific part which is described in 'focus_part' edje data.
+ *
+ * @param obj Widget object for the focus highlight
+ * @param x Focus highlight x coordinate
+ * @param y Focus highlight y coordinate
+ * @param w Focus highlight object width
+ * @param h Focus highlight object height
+ *
+ * x, y, w, h already contain the object's geometry. If there is a 'focus_part'
+ * support, these values will be updated accordingly or the values will be
+ * remained as they were.
+ *
+ * @ingroup Widget
+ */
+EAPI void
+elm_widget_focus_highlight_focus_part_geometry_get(const Evas_Object *obj,
+ Evas_Coord *x,
+ Evas_Coord *y,
+ Evas_Coord *w,
+ Evas_Coord *h)
{
- Elm_Widget_Smart_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
- if (!sd) return NULL;
+ Evas_Coord tx = 0, ty = 0, tw = 0, th = 0;
+ const char *target_hl_part = NULL;
+ const Evas_Object *edje_obj = NULL;
- if (!sd->theme)
+ if (obj && efl_isa(obj, EFL_CANVAS_LAYOUT_CLASS))
{
- if (sd->parent_obj && elm_widget_is(sd->parent_obj))
- return elm_widget_theme_get(sd->parent_obj);
- else return NULL;
+ edje_obj = obj;
+ if (!(target_hl_part = edje_object_data_get(edje_obj, "focus_part")))
+ return;
}
- return sd->theme;
-}
-
-EOLIAN static Efl_Ui_Theme_Apply_Result
-_efl_ui_widget_style_set(Eo *obj, Elm_Widget_Smart_Data *sd, const char *style)
-{
- if (!elm_widget_is_legacy(obj) && efl_finalized_get(obj))
+ else if (obj && efl_isa(obj, EFL_UI_LAYOUT_CLASS))
{
- ERR("Efl.Ui.Widget.style can only be set before finalize!");
- return EFL_UI_THEME_APPLY_RESULT_FAIL;
+ edje_obj = elm_layout_edje_get(obj);
+ if (!(target_hl_part = elm_layout_data_get(obj, "focus_part")))
+ return;
}
+ else
+ return;
- if (eina_stringshare_replace(&sd->style, style))
- return elm_widget_theme(obj);
-
- return EFL_UI_THEME_APPLY_RESULT_SUCCESS;
+ edje_object_part_geometry_get(edje_obj, target_hl_part,
+ &tx, &ty, &tw, &th);
+ *x += tx;
+ *y += ty;
+ if (tw != *w) *w = tw;
+ if (th != *h) *h = th;
}
-EOLIAN static const char*
-_efl_ui_widget_style_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
+EOLIAN static Eina_Rect
+_efl_ui_widget_focus_highlight_geometry_get(const Eo *obj, Elm_Widget_Smart_Data *sd)
{
- const char *ret;
- ret = "default";
- if (sd->style) ret = sd->style;
+ Evas_Coord ox = 0, oy = 0, ow = 0, oh = 0;
+ Evas_Object *scroller = (Evas_Object *)obj;
+ Eina_Rect r = {};
- return ret;
-}
+ evas_object_geometry_get(obj, &r.x, &r.y, &r.w, &r.h);
+ elm_widget_focus_highlight_focus_part_geometry_get(sd->resize_obj, &r.x, &r.y, &r.w, &r.h);
-EAPI void
-elm_widget_tooltip_add(Eo *obj, Elm_Tooltip *tt)
-{
- Elm_Widget_Smart_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
- if (!sd) return;
+ if (_elm_config->focus_autoscroll_mode != ELM_FOCUS_AUTOSCROLL_MODE_BRING_IN)
+ return r;
- sd->tooltips = eina_list_append(sd->tooltips, tt);
-}
+ while (scroller)
+ {
+ if (_elm_scrollable_is(scroller))
+ {
+ elm_interface_scrollable_content_viewport_geometry_get(scroller, &ox, &oy, &ow, &oh);
-EAPI void
-elm_widget_tooltip_del(Eo *obj, Elm_Tooltip *tt)
-{
- Elm_Widget_Smart_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
- if (!sd) return;
+ if (r.y < oy)
+ r.y = oy;
+ else if ((oy + oh) < (r.y + r.h))
+ r.y = (oy + oh - r.h);
+ else if (r.x < ox)
+ r.x = ox;
+ else if ((ox + ow) < (r.x + r.w))
+ r.x = (ox + ow - r.w);
- sd->tooltips = eina_list_remove(sd->tooltips, tt);
+ break;
+ }
+ scroller = elm_widget_parent_get(scroller);
+ }
+
+ return r;
}
EAPI void
-elm_widget_cursor_add(Eo *obj, Elm_Cursor *cur)
+elm_widget_activate(Evas_Object *obj, Efl_Ui_Activate act)
{
- Elm_Widget_Smart_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
- if (!sd) return;
+ Evas_Object *parent;
+ Eina_Bool ret;
- sd->cursors = eina_list_append(sd->cursors, cur);
-}
+ ELM_WIDGET_CHECK(obj);
-EAPI void
-elm_widget_cursor_del(Eo *obj, Elm_Cursor *cur)
-{
- Elm_Widget_Smart_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
- if (!sd) return;
+ ret = EINA_FALSE;
- sd->cursors = eina_list_remove(sd->cursors, cur);
+ ret = efl_ui_widget_on_access_activate(obj, act);
+
+ if (ret) return;
+
+ parent = elm_widget_parent_get(obj);
+ if (parent)
+ elm_widget_activate(parent, act);
+
+ return;
}
+/**
+ * @internal
+ *
+ * Sets the widget and child widget's Evas_Display_Mode.
+ *
+ * @param obj The widget.
+ * @param dispmode Evas_Display_Mode to set widget's mode.
+ *
+ * Widgets are resized by several reasons.
+ * Evas_Display_Mode can help for widgets to get one more reason of resize.
+ * For example, elm conform widget resizes it's contents when keypad state changed.
+ * After keypad showing, conform widget can change child's Evas_Display_Mode.
+ * @ingroup Widget
+ */
+/* Legacy only */
EAPI void
-elm_widget_scroll_lock_set(Eo *obj, Efl_Ui_Scroll_Block block)
+elm_widget_display_mode_set(Evas_Object *obj, Evas_Display_Mode dispmode)
{
- Elm_Widget_Smart_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
- Eina_Bool lx, ly;
+ Evas_Display_Mode prev_dispmode;
+ Evas_Object *child;
+ Eina_List *l;
- if (!sd) return;
- lx = !!(block & EFL_UI_SCROLL_BLOCK_HORIZONTAL);
- ly = !!(block & EFL_UI_SCROLL_BLOCK_VERTICAL);
- if (sd->scroll_x_locked != lx)
- {
- sd->scroll_x_locked = lx;
- _propagate_x_drag_lock(obj, lx ? 1 : -1);
- }
- if (sd->scroll_y_locked != ly)
+ API_ENTRY return;
+ prev_dispmode = evas_object_size_hint_display_mode_get(obj);
+
+ if ((prev_dispmode == dispmode) ||
+ (prev_dispmode == EVAS_DISPLAY_MODE_DONT_CHANGE)) return;
+
+ evas_object_size_hint_display_mode_set(obj, dispmode);
+
+ EINA_LIST_FOREACH (sd->subobjs, l, child)
{
- sd->scroll_y_locked = ly;
- _propagate_y_drag_lock(obj, ly ? 1 : -1);
+ if (elm_widget_is(child))
+ elm_widget_display_mode_set(child, dispmode);
}
}
-EAPI Efl_Ui_Scroll_Block
-elm_widget_scroll_lock_get(const Eo *obj)
+EOLIAN static void
+_efl_ui_widget_orientation_mode_set(Eo *obj, Elm_Widget_Smart_Data *sd, Efl_Ui_Widget_Orientation_Mode mode)
{
- Elm_Widget_Smart_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
- Efl_Ui_Scroll_Block block = EFL_UI_SCROLL_BLOCK_NONE;
-
- if (!sd) return block;
- if (sd->scroll_x_locked) block |= EFL_UI_SCROLL_BLOCK_HORIZONTAL;
- if (sd->scroll_y_locked) block |= EFL_UI_SCROLL_BLOCK_VERTICAL;
+ int rotation = -1;
- return block;
+ if (mode != EFL_UI_WIDGET_ORIENTATION_MODE_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) rotation = 0;
+ else rotation = sd_parent->orient_mode;
+ }
+ efl_ui_widget_on_orientation_update(obj, rotation);
}
-EAPI int
-elm_widget_scroll_child_locked_x_get(const Eo *obj)
+EOLIAN static Efl_Ui_Widget_Orientation_Mode
+_efl_ui_widget_orientation_mode_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
{
- Elm_Widget_Smart_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
- if (!sd) return EINA_FALSE;
- return sd->child_drag_x_locked;
+ if (sd->orient_mode == -1) return EFL_UI_WIDGET_ORIENTATION_MODE_DISABLED;
+ else return EFL_UI_WIDGET_ORIENTATION_MODE_DEFAULT;
}
-EAPI int
-elm_widget_scroll_child_locked_y_get(const Eo *obj)
+EOLIAN static void
+_efl_ui_widget_on_orientation_update(Eo *obj, Elm_Widget_Smart_Data *sd, int orient_mode)
{
- Elm_Widget_Smart_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
- if (!sd) return EINA_FALSE;
- return sd->child_drag_y_locked;
-}
+ Evas_Object *child;
+ Eina_List *l;
-EAPI Efl_Ui_Theme_Apply_Result
-elm_widget_theme_object_set(Evas_Object *obj, Evas_Object *edj, const char *wname, const char *welement, const char *wstyle)
-{
- Elm_Widget_Smart_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
- if (!sd) return EFL_UI_THEME_APPLY_RESULT_FAIL;
+ sd->orient_mode = orient_mode;
- if (eina_streq(welement, "base"))
- welement = NULL;
- if (eina_streq(wstyle, "default"))
- wstyle = NULL;
- Efl_Ui_Theme_Apply_Result ret = _elm_theme_object_set(obj, edj, wname, welement, wstyle);
- if (!ret)
+ EINA_LIST_FOREACH (sd->subobjs, l, child)
{
- return EFL_UI_THEME_APPLY_RESULT_FAIL;
+ if (elm_widget_is(child))
+ efl_ui_widget_on_orientation_update(child, orient_mode);
}
- if (sd->orient_mode != -1)
+ if (orient_mode != -1)
{
char buf[128];
if (elm_widget_is_legacy(obj))
{
- snprintf(buf, sizeof(buf), "elm,state,orient,%d", sd->orient_mode);
+ snprintf(buf, sizeof(buf), "elm,state,orient,%d", orient_mode);
elm_widget_signal_emit(obj, buf, "elm");
}
else
{
- snprintf(buf, sizeof(buf), "efl,state,orient,%d", sd->orient_mode);
+ snprintf(buf, sizeof(buf), "efl,state,orient,%d", orient_mode);
elm_widget_signal_emit(obj, buf, "efl");
}
}
-
- return ret;
}
-static void
-_convert(Efl_Dbg_Info *info, Eina_Iterator *ptr_list)
+/**
+ * @internal
+ *
+ * Returns the widget's focus move policy.
+ *
+ * @param obj The widget.
+ * @return focus move policy of the object.
+ *
+ **/
+EOLIAN static Elm_Focus_Move_Policy
+_efl_ui_widget_focus_move_policy_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
{
- void *p;
- int i = 0;
-
- EINA_ITERATOR_FOREACH(ptr_list, p)
- {
- char name[100];
+ return sd->focus_move_policy;
+}
- snprintf(name, sizeof(name), "Candidate %d", i);
+/**
+ * @internal
+ *
+ * Sets the widget's focus move policy.
+ *
+ * @param obj The widget.
+ * @param policy Elm_Focus_Move_Policy to set object's focus move policy.
+ */
- EFL_DBG_INFO_APPEND(info, name, EINA_VALUE_TYPE_UINT64, p);
- i++;
- }
+EOLIAN static void
+_efl_ui_widget_focus_move_policy_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, Elm_Focus_Move_Policy policy)
+{
+ if (sd->focus_move_policy == policy) return;
+ sd->focus_move_policy = policy;
+}
- eina_iterator_free(ptr_list);
+/**
+ * Returns the widget's focus_move_policy mode setting.
+ *
+ * @param obj The widget.
+ * @return focus_move_policy mode setting of the object.
+ *
+ **/
+EOLIAN static Eina_Bool
+_efl_ui_widget_focus_move_policy_automatic_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
+{
+ return sd->focus_move_policy_auto_mode;
}
+/**
+ * @internal
+ *
+ * Sets the widget's focus_move_policy mode setting.
+ * When widget in automatic mode, it follows the system focus_move_policy mode set by
+ * elm_config_focus_move_policy_set().
+ * @param obj The widget.
+ * @param automatic EINA_TRUE for auto focus_move_policy mode. EINA_FALSE for manual.
+ */
EOLIAN static void
-_efl_ui_widget_efl_object_dbg_info_get(Eo *eo_obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED, Efl_Dbg_Info *root)
+_efl_ui_widget_focus_move_policy_automatic_set(Eo *obj, Elm_Widget_Smart_Data *sd, Eina_Bool automatic)
{
- efl_dbg_info_get(efl_super(eo_obj, MY_CLASS), root);
- Efl_Ui_Focus_Relations *rel = NULL;
- Efl_Dbg_Info *focus, *group = EFL_DBG_INFO_LIST_APPEND(root, MY_CLASS_NAME);
-
- EFL_DBG_INFO_APPEND(group, "Wid-Type", EINA_VALUE_TYPE_STRING, elm_widget_type_get(eo_obj));
- EFL_DBG_INFO_APPEND(group, "Style", EINA_VALUE_TYPE_STRING, elm_widget_style_get(eo_obj));
- EFL_DBG_INFO_APPEND(group, "Layer", EINA_VALUE_TYPE_INT,
- (int) evas_object_layer_get(eo_obj));
- EFL_DBG_INFO_APPEND(group, "Scale", EINA_VALUE_TYPE_DOUBLE,
- evas_object_scale_get(eo_obj));
- EFL_DBG_INFO_APPEND(group, "Has focus", EINA_VALUE_TYPE_CHAR,
- elm_object_focus_get(eo_obj));
- EFL_DBG_INFO_APPEND(group, "Can focus", EINA_VALUE_TYPE_CHAR,
- elm_widget_can_focus_get(eo_obj));
- EFL_DBG_INFO_APPEND(group, "Disabled", EINA_VALUE_TYPE_CHAR,
- elm_widget_disabled_get(eo_obj));
- EFL_DBG_INFO_APPEND(group, "Mirrored", EINA_VALUE_TYPE_CHAR,
- efl_ui_mirrored_get(eo_obj));
- EFL_DBG_INFO_APPEND(group, "Tree Unfocusable", EINA_VALUE_TYPE_CHAR,
- elm_widget_tree_unfocusable_get(eo_obj));
- EFL_DBG_INFO_APPEND(group, "Automatic mirroring", EINA_VALUE_TYPE_CHAR,
- efl_ui_mirrored_automatic_get(eo_obj));
-
- rel = efl_ui_focus_manager_fetch(_pd->focus.manager, eo_obj);
- if (rel)
- {
- focus = EFL_DBG_INFO_LIST_APPEND(group, "Focus");
-
- EFL_DBG_INFO_APPEND(focus, "logical", EINA_VALUE_TYPE_CHAR, rel->logical );
- EFL_DBG_INFO_APPEND(focus, "manager", EINA_VALUE_TYPE_UINT64, _pd->focus.manager);
- EFL_DBG_INFO_APPEND(focus, "parent", EINA_VALUE_TYPE_UINT64, rel->parent);
- EFL_DBG_INFO_APPEND(focus, "next", EINA_VALUE_TYPE_UINT64 , rel->next);
- EFL_DBG_INFO_APPEND(focus, "prev", EINA_VALUE_TYPE_UINT64 , rel->prev);
-
- EFL_DBG_INFO_APPEND(focus, "redirect", EINA_VALUE_TYPE_UINT64 , rel->redirect);
-
-#define ADD_PTR_LIST(name) \
- Efl_Dbg_Info* name = EFL_DBG_INFO_LIST_APPEND(focus, ""#name""); \
- _convert(name, eina_list_iterator_new(rel->name));
-
- ADD_PTR_LIST(top)
- ADD_PTR_LIST(down)
- ADD_PTR_LIST(right)
- ADD_PTR_LIST(left)
-
-#undef ADD_PTR_LIST
-
- }
-
- //if thats a focus manager, give useful information like the border elements
- if (efl_isa(eo_obj, EFL_UI_FOCUS_MANAGER_INTERFACE))
+ if (sd->focus_move_policy_auto_mode != automatic)
{
- Efl_Dbg_Info *border;
-
- focus = EFL_DBG_INFO_LIST_APPEND(group, "Focus Manager");
- border = EFL_DBG_INFO_LIST_APPEND(focus, "Border Elements");
-
- _convert(border,
- efl_ui_focus_manager_border_elements_get(eo_obj)
- );
+ sd->focus_move_policy_auto_mode = automatic;
- EFL_DBG_INFO_APPEND(focus, "redirect", EINA_VALUE_TYPE_UINT64,
- efl_ui_focus_manager_redirect_get(eo_obj));
+ if (automatic)
+ {
+ efl_ui_widget_focus_move_policy_set(obj, elm_config_focus_move_policy_get());
+ }
}
}
+/**
+ * @internal
+ *
+ * Sets the klass name of a widget.
+ * @param obj The widget.
+ * @param name Name of the klass to use.
+ * @return Whether the name was different and thus replaced.
+ */
EAPI Eina_Bool
-elm_widget_is_check(const Evas_Object *obj)
+elm_widget_theme_klass_set(Evas_Object *obj, const char *name)
{
- static int abort_on_warn = -1;
- if (elm_widget_is(obj))
- return EINA_TRUE;
+ Elm_Widget_Smart_Data *pd = efl_data_scope_safe_get(obj, MY_CLASS);
+ if (!pd) return EINA_FALSE;
- ERR("Passing Object: %p.", obj);
- if (abort_on_warn == -1)
- {
- if (getenv("ELM_ERROR_ABORT")) abort_on_warn = 1;
- else abort_on_warn = 0;
- }
- if (abort_on_warn == 1) abort();
- return EINA_FALSE;
+ return eina_stringshare_replace(&(pd->klass), name);
}
-/* If you changed a legacy widget's class name,
- * please update the "legacy_type_table". */
+/**
+ * @internal
+ *
+ * Gets the klass name of a widget.
+ * @param obj The widget.
+ * @return The current klass name of internal canvas object.
+ */
EAPI const char *
-elm_widget_type_get(const Evas_Object *obj)
+elm_widget_theme_klass_get(const Evas_Object *obj)
{
- const char *ret;
- int i;
+ Elm_Widget_Smart_Data *pd = efl_data_scope_safe_get(obj, MY_CLASS);
+ if (!pd) return NULL;
- API_ENTRY return NULL;
+ return (const char *)pd->klass;
+}
- ret = efl_class_name_get(efl_class_get(obj));
+/**
+ * @internal
+ *
+ * Sets the element name of a widget.
+ *
+ * @param obj The widget.
+ * @param name Name of the element to use.
+ * @return Whether the name was different and thus replaced.
+ */
+EAPI Eina_Bool
+elm_widget_theme_element_set(Evas_Object *obj, const char *name)
+{
+ Elm_Widget_Smart_Data *pd = efl_data_scope_safe_get(obj, MY_CLASS);
+ if (!pd) return EINA_FALSE;
- /* If the given widget is created for legacy,
- * convert type name to legacy. */
- if (elm_widget_is_legacy(obj))
- {
- for (i = 0; legacy_type_table[i][0] ; i++)
- {
- if (eina_streq(ret, legacy_type_table[i][0]))
- return legacy_type_table[i][1];
- }
- }
+ if (eina_streq(name, "base"))
+ name = NULL;
- return ret;
+ return eina_stringshare_replace(&(pd->group), name);
}
-/* TIZEN_ONLY(20180504): add missing item class names and fix edje_class parse rule for legacy */
-const char *
-_elm_widget_item_legacy_type_get(const Evas_Object *obj)
+/**
+ * @internal
+ *
+ * Gets the element name of a widget.
+ * @param obj The widget.
+ * @return The current element name of internal canvas object.
+ */
+EAPI const char *
+elm_widget_theme_element_get(const Evas_Object *obj)
{
- const char *ret;
- int i;
-
- ret = efl_class_name_get(efl_class_get(obj));
-
- /* If the given widget is created for legacy,
- * convert type name to legacy. */
- for (i = 0; legacy_type_table[i][0] ; i++)
- {
- if (eina_streq(ret, legacy_type_table[i][0]))
- return legacy_type_table[i][1];
- }
+ Elm_Widget_Smart_Data *pd = efl_data_scope_safe_get(obj, MY_CLASS);
+ if (!pd) return NULL;
- return ret;
+ return (const char *)pd->group;
}
-/* END */
+/**
+ * @internal
+ *
+ * Sets the style name of a widget.
+ *
+ * @param obj The widget.
+ * @param name Name of the style to use.
+ * @return Whether the name was different and thus replaced.
+ */
EAPI Eina_Bool
-elm_widget_type_check(const Evas_Object *obj,
- const char *type,
- const char *func)
+elm_widget_theme_style_set(Evas_Object *obj, const char *name)
{
- const char *provided, *expected = "(unknown)";
- static int abort_on_warn = -1;
+ Elm_Widget_Smart_Data *pd = efl_data_scope_safe_get(obj, MY_CLASS);
+ if (!pd) return EINA_FALSE;
- provided = elm_widget_type_get(obj);
- /* TODO: eventually migrate to check_ptr version */
- if (evas_object_smart_type_check(obj, type)) return EINA_TRUE;
- if (type) expected = type;
- if ((!provided) || (!provided[0]))
- {
- provided = evas_object_type_get(obj);
- if ((!provided) || (!provided[0]))
- provided = "(unknown)";
- }
- ERR("Passing Object: %p in function: %s, of type: '%s' when expecting"
- " type: '%s'", obj, func, provided, expected);
- if (abort_on_warn == -1)
- {
- if (getenv("ELM_ERROR_ABORT")) abort_on_warn = 1;
- else abort_on_warn = 0;
- }
- if (abort_on_warn == 1) abort();
- return EINA_FALSE;
+ if (eina_streq(name, "default"))
+ name = NULL;
+
+ return eina_stringshare_replace(&(pd->style), name);
}
-/** @internal */
-EAPI Evas_Object *
-elm_widget_name_find(const Eo *obj, const char *name, int recurse)
+/**
+ * @internal
+ *
+ * Gets the style name of a widget.
+ * @param obj The widget.
+ * @return The current style name of internal canvas object.
+ */
+EAPI const char *
+elm_widget_theme_style_get(const Evas_Object *obj)
{
- Eina_List *l;
- Evas_Object *child;
- const char *s;
- INTERNAL_ENTRY NULL;
+ Elm_Widget_Smart_Data *pd = efl_data_scope_safe_get(obj, MY_CLASS);
+ if (!pd) return NULL;
- if (!name) return NULL;
- if (!_elm_widget_is(obj)) return NULL;
- EINA_LIST_FOREACH(sd->subobjs, l, child)
- {
- s = evas_object_name_get(child);
- if ((s) && (!strcmp(s, name))) return child;
- if ((recurse != 0) &&
- ((child = elm_widget_name_find(child, name, recurse - 1))))
- return child;
- }
- if (sd->hover_obj)
- {
- s = evas_object_name_get(sd->hover_obj);
- if ((s) && (!strcmp(s, name))) return sd->hover_obj;
- if ((recurse != 0) &&
- ((child = elm_widget_name_find(sd->hover_obj, name, recurse - 1))))
- return child;
- }
- return NULL;
+ return (const char *)pd->style;
}
/**
* @internal
*
- * Split string in words
- *
- * @param str Source string
- * @return List of const words
- *
- * @see elm_widget_stringlist_free()
- * @ingroup Widget
+ * Register sub object as a group of a widget and re-apply its theme.
+ * @param obj The widget.
+ * @param component A sub object to be added as an element of the widget.
+ * @param name An element name of sub object.
+ * @return Whether the style was successfully applied or not.
*/
-EAPI Eina_List *
-elm_widget_stringlist_get(const char *str)
+EAPI Efl_Ui_Theme_Apply_Result
+elm_widget_element_update(Evas_Object *obj, Evas_Object *component, const char *name)
{
- Eina_List *list = NULL;
- const char *s, *b;
- if (!str) return NULL;
- for (b = s = str; 1; s++)
+ Efl_Ui_Theme_Apply_Result ret = EFL_UI_THEME_APPLY_RESULT_SUCCESS;
+ Eina_Bool changed = EINA_FALSE;
+ const char *obj_group;
+ Eina_Stringshare *group;
+
+ obj_group = elm_widget_theme_element_get(obj);
+ if (!obj_group)
+ group = eina_stringshare_add(name);
+ else
+ group = eina_stringshare_printf("%s/%s", elm_widget_theme_element_get(obj), name);
+ if (efl_isa(component, EFL_UI_WIDGET_CLASS))
{
- if ((*s == ' ') || (!*s))
- {
- char *t = malloc(s - b + 1);
- if (t)
- {
- strncpy(t, b, s - b);
- t[s - b] = 0;
- list = eina_list_append(list, eina_stringshare_add(t));
- free(t);
- }
- b = s + 1;
- }
- if (!*s) break;
+ changed |= elm_widget_theme_klass_set(component, elm_widget_theme_klass_get(obj));
+ changed |= elm_widget_theme_element_set(component, (const char *)group);
+ changed |= elm_widget_theme_style_set(component, elm_widget_theme_style_get(obj));
+ if (changed)
+ ret = efl_ui_widget_theme_apply(component);
}
- return list;
+ else
+ {
+ ret = elm_widget_theme_object_set(obj, component,
+ elm_widget_theme_klass_get(obj),
+ (const char *)group,
+ elm_widget_theme_style_get(obj));
+ }
+ eina_stringshare_del(group);
+
+ return ret;
}
-EAPI void
-elm_widget_stringlist_free(Eina_List *list)
+static void
+_track_obj_del(void *data, Evas *e, Evas_Object *obj, void *event_info);
+
+static void
+_track_obj_update(Evas_Object *track, Evas_Object *obj)
{
- const char *s;
- EINA_LIST_FREE(list, s)
- eina_stringshare_del(s);
+ //Geometry
+ Evas_Coord x, y, w, h;
+ evas_object_geometry_get(obj, &x, &y, &w, &h);
+ evas_object_move(track, x, y);
+ evas_object_resize(track, w, h);
+
+ //Visibility
+ if (evas_object_visible_get(obj)) evas_object_show(track);
+ else evas_object_hide(track);
}
-//TIZEN_ONLY(20180607): Restore legacy focus
-EOLIAN static void
-_efl_ui_widget_focus_hide_handle(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
+
+static void
+_track_obj_view_update(void *data, const Efl_Event *event)
{
- if (!_elm_widget_is(obj))
- return;
- _if_focused_revert(obj, EINA_TRUE);
+ Elm_Widget_Item_Data *item = data;
+ _track_obj_update(item->track_obj, event->object);
}
-//
-/* internal */
-EAPI void
-elm_widget_focus_mouse_up_handle(Eo *obj)
-{
- Elm_Widget_Smart_Data *pd = efl_data_scope_get(obj, MY_CLASS);
- if (!_is_focusable(obj)) return;
+static void
+_track_obj_view_del(void *data, const Efl_Event *event);
- //TIZEN_ONLY(20180607): Restore legacy focus
- if (elm_widget_is_legacy(obj))
- {
- Evas_Object *o = obj;
- do
- {
- if (_elm_widget_is(o)) break;
- o = evas_object_smart_parent_get(o);
- }
- while (o);
+EFL_CALLBACKS_ARRAY_DEFINE(tracker_callbacks,
+ { EFL_GFX_ENTITY_EVENT_SIZE_CHANGED, _track_obj_view_update },
+ { EFL_GFX_ENTITY_EVENT_POSITION_CHANGED, _track_obj_view_update },
+ { EFL_GFX_ENTITY_EVENT_SHOW, _track_obj_view_update },
+ { EFL_GFX_ENTITY_EVENT_HIDE, _track_obj_view_update },
+ { EFL_EVENT_DEL, _track_obj_view_del });
- efl_ui_widget_focus_mouse_up_handle(o);
- return;
- }
- //
- if (pd->focus.manager && !pd->focus.logical)
- {
- efl_ui_focus_util_focus(obj);
- }
-}
-//TIZEN_ONLY(20180607): Restore legacy focus
-EOLIAN static void
-_efl_ui_widget_focus_mouse_up_handle(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
+static void
+_track_obj_view_del(void *data, const Efl_Event *event EINA_UNUSED)
{
- if (!obj) return;
- if (!_is_focusable(obj)) return;
+ Elm_Widget_Item_Data *item = data;
- efl_ui_widget_focus_steal(obj, NULL);
-}
+ while (evas_object_ref_get(item->track_obj) > 0)
+ evas_object_unref(item->track_obj);
-EOLIAN static void
-_efl_ui_widget_focus_tree_unfocusable_handle(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
-{
- if (!elm_widget_parent_get(obj))
- efl_ui_widget_focused_object_clear(obj);
- else
- _if_focused_revert(obj, EINA_TRUE);
+ evas_object_event_callback_del(item->track_obj, EVAS_CALLBACK_DEL,
+ _track_obj_del);
+ evas_object_del(item->track_obj);
+ item->track_obj = NULL;
}
-EOLIAN static void
-_efl_ui_widget_focus_disabled_handle(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
+static void
+_track_obj_del(void *data, Evas *e EINA_UNUSED,
+ Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
- efl_ui_widget_focus_tree_unfocusable_handle(obj);
+ Elm_Widget_Item_Data *item = data;
+ item->track_obj = NULL;
+
+ if (!item->view) return;
+
+ efl_event_callback_array_del(item->view, tracker_callbacks(), item);
}
-EOLIAN static unsigned int
-_efl_ui_widget_focus_order_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
+static void
+_elm_widget_item_signal_cb(void *data, Evas_Object *obj EINA_UNUSED, const char *emission,
+ const char *source)
{
- return sd->focus_order;
+ Elm_Widget_Item_Signal_Data *wisd = data;
+ wisd->func(wisd->data, wisd->item, emission, source);
}
-EOLIAN static Evas_Object*
-_efl_ui_widget_newest_focus_order_get(const Eo *obj, Elm_Widget_Smart_Data *sd, unsigned int *newest_focus_order, Eina_Bool can_focus_only)
+static void *
+_elm_widget_item_signal_callback_list_get(Elm_Widget_Item_Data *item, Eina_List *position)
{
- const Eina_List *l;
- Evas_Object *child, *cur, *best;
-
- if (!evas_object_visible_get(obj)
- || (elm_widget_disabled_get(obj))
- || (elm_widget_tree_unfocusable_get(obj)))
- return NULL;
+ Elm_Widget_Item_Signal_Data *wisd = eina_list_data_get(position);
+ void *data;
- 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;
+ item->signals = eina_list_remove_list(item->signals, position);
+ data = wisd->data;
- cur = efl_ui_widget_newest_focus_order_get
- (child, newest_focus_order, can_focus_only);
- if (!cur) continue;
- best = cur;
- }
- return best;
-}
+ if (_elm_widget_is(item->view))
+ elm_object_signal_callback_del(item->view,
+ wisd->emission, wisd->source,
+ _elm_widget_item_signal_cb);
+ else if (efl_isa(item->view, EFL_CANVAS_LAYOUT_CLASS))
+ edje_object_signal_callback_del_full(item->view,
+ wisd->emission, wisd->source,
+ _elm_widget_item_signal_cb, wisd);
-EOLIAN static Eina_Bool
-_efl_ui_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;
+ eina_stringshare_del(wisd->emission);
+ eina_stringshare_del(wisd->source);
+ free(wisd);
+
+ return data;
}
-static Eina_Bool
-_efl_ui_widget_focus_direction_manager_is(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
+#define ERR_NOT_SUPPORTED(item, method) ERR("%s does not support %s API.", elm_widget_type_get(item->widget), method);
+
+static void
+_efl_del_cb(void *data EINA_UNUSED, const Efl_Event *event)
{
- 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;
+ Elm_Widget_Item_Data *item = efl_data_scope_get(event->object, ELM_WIDGET_ITEM_CLASS);
+ ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
+ if (item->del_func)
+ item->del_func((void *) WIDGET_ITEM_DATA_GET(event->object), item->widget, item->eo_obj);
}
-//
-/*
- * @internal
- *
- * Get the focus highlight geometry of a widget.
- *
- * @param obj Widget object for the focus highlight
- * @param x Focus highlight x coordinate
- * @param y Focus highlight y coordinate
- * @param w Focus highlight object width
- * @param h Focus highlight object height
- * @param is_next @c EINA_TRUE if this request is for the new focused object,
- * @c EINA_FALSE if this request is for the previously focused object. This
- * information becomes important when the focus highlight is changed inside one
- * widget.
- *
- * @ingroup Widget
- */
-/*
+
+/**
* @internal
*
- * Get the 'focus_part' geometry if there is any
+ * Allocate a new Elm_Widget_Item-derived structure.
*
- * This queries if there is a 'focus_part' request from the edc style. If edc
- * style offers 'focus_part' edje data item, this function requests for the
- * geometry of a specific part which is described in 'focus_part' edje data.
+ * The goal of this structure is to provide common ground for actions
+ * that a widget item have, such as the owner widget, callback to
+ * notify deletion, data pointer and maybe more.
*
- * @param obj Widget object for the focus highlight
- * @param x Focus highlight x coordinate
- * @param y Focus highlight y coordinate
- * @param w Focus highlight object width
- * @param h Focus highlight object height
+ * @param widget the owner widget that holds this item, must be an elm_widget!
+ * @param alloc_size any number greater than sizeof(Elm_Widget_Item) that will
+ * be used to allocate memory.
*
- * x, y, w, h already contain the object's geometry. If there is a 'focus_part'
- * support, these values will be updated accordingly or the values will be
- * remained as they were.
+ * @return allocated memory that is already zeroed out, or NULL on errors.
*
+ * @see elm_widget_item_new() convenience macro.
+ * @see elm_widget_item_del() to release memory.
* @ingroup Widget
*/
-EAPI void
-elm_widget_focus_highlight_focus_part_geometry_get(const Evas_Object *obj,
- Evas_Coord *x,
- Evas_Coord *y,
- Evas_Coord *w,
- Evas_Coord *h)
+EOLIAN static Eo *
+_elm_widget_item_efl_object_constructor(Eo *eo_item, Elm_Widget_Item_Data *item)
{
- Evas_Coord tx = 0, ty = 0, tw = 0, th = 0;
- const char *target_hl_part = NULL;
- const Evas_Object *edje_obj = NULL;
+ Evas_Object *widget;
+ widget = efl_parent_get(eo_item);
- if (obj && efl_isa(obj, EFL_CANVAS_LAYOUT_CLASS))
- {
- edje_obj = obj;
- if (!(target_hl_part = edje_object_data_get(edje_obj, "focus_part")))
- return;
- }
- else if (obj && efl_isa(obj, EFL_UI_LAYOUT_CLASS))
+ if (!_elm_widget_is(widget))
{
- edje_obj = elm_layout_edje_get(obj);
- if (!(target_hl_part = elm_layout_data_get(obj, "focus_part")))
- return;
+ ERR("Failed");
+ return NULL;
}
- else
- return;
- edje_object_part_geometry_get(edje_obj, target_hl_part,
- &tx, &ty, &tw, &th);
- *x += tx;
- *y += ty;
- if (tw != *w) *w = tw;
- if (th != *h) *h = th;
-}
+ eo_item = efl_constructor(efl_super(eo_item, ELM_WIDGET_ITEM_CLASS));
-EOLIAN static Eina_Rect
-_efl_ui_widget_focus_highlight_geometry_get(const Eo *obj, Elm_Widget_Smart_Data *sd)
-{
- Evas_Coord ox = 0, oy = 0, ow = 0, oh = 0;
- Evas_Object *scroller = (Evas_Object *)obj;
- Eina_Rect r = {};
+ EINA_MAGIC_SET(item, ELM_WIDGET_ITEM_MAGIC);
- evas_object_geometry_get(obj, &r.x, &r.y, &r.w, &r.h);
- elm_widget_focus_highlight_focus_part_geometry_get(sd->resize_obj, &r.x, &r.y, &r.w, &r.h);
+ item->widget = widget;
+ item->eo_obj = eo_item;
+ //TIZEN_ONLY(20170717) : expose highlight information on atspi
+ item->can_highlight = EINA_TRUE;
+ //
+ efl_event_callback_add(eo_item, EFL_EVENT_DEL, _efl_del_cb, NULL);
- if (_elm_config->focus_autoscroll_mode != ELM_FOCUS_AUTOSCROLL_MODE_BRING_IN)
- return r;
+ return eo_item;
+}
- while (scroller)
- {
- if (_elm_scrollable_is(scroller))
- {
- elm_interface_scrollable_content_viewport_geometry_get(scroller, &ox, &oy, &ow, &oh);
+EOLIAN static void
+_elm_widget_item_efl_object_destructor(Eo *eo_item, Elm_Widget_Item_Data *item)
+{
+ Elm_Translate_String_Data *ts;
- if (r.y < oy)
- r.y = oy;
- else if ((oy + oh) < (r.y + r.h))
- r.y = (oy + oh - r.h);
- else if (r.x < ox)
- r.x = ox;
- else if ((ox + ow) < (r.x + r.w))
- r.x = (ox + ow - r.w);
+ ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
- break;
- }
- scroller = elm_widget_parent_get(scroller);
- }
+ eina_stringshare_del(item->style);
+ eina_stringshare_del(item->access_info);
+ eina_stringshare_del(item->accessible_name);
- return r;
-}
+ while (item->signals)
+ _elm_widget_item_signal_callback_list_get(item, item->signals);
-EOLIAN static Elm_Object_Item*
-_efl_ui_widget_focused_item_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
-{
- return NULL;
-}
+ while (item->translate_strings)
+ {
+ ts = EINA_INLIST_CONTAINER_GET(item->translate_strings,
+ Elm_Translate_String_Data);
+ eina_stringshare_del(ts->id);
+ eina_stringshare_del(ts->domain);
+ eina_stringshare_del(ts->string);
+ item->translate_strings = eina_inlist_remove(item->translate_strings,
+ item->translate_strings);
+ free(ts);
+ }
+ eina_hash_free(item->labels);
-EOLIAN static void
-_efl_ui_widget_interest_region_mode_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd, Elm_Focus_Region_Show_Mode mode)
-{
- _pd->focus_region_show_mode = mode;
-}
+ //TIZEN_ONLY : elm_widget_item: add at-spi name setter
+ efl_access_object_description_set(eo_item, NULL);
+ efl_access_object_i18n_name_set(eo_item, NULL);
-EOLIAN static Elm_Focus_Region_Show_Mode
-_efl_ui_widget_interest_region_mode_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd)
-{
- return _pd->focus_region_show_mode;
-}
+ efl_access_object_description_cb_set(eo_item, NULL, NULL);
+ efl_access_object_name_cb_set(eo_item, NULL, NULL);
+ //
+ //TIZEN_ONLY(20170405) Add gesture method to accessible interface
+ efl_access_object_gesture_cb_set(eo_item, NULL, NULL);
+ //
+ //TIZEN_ONLY : elm_widget_item: add at-spi name setter
+ efl_access_object_translation_domain_set(eo_item, NULL);
+ efl_access_object_relationships_clear(eo_item);
+ //
-EAPI void
-elm_widget_activate(Evas_Object *obj, Efl_Ui_Activate act)
-{
- Evas_Object *parent;
- Eina_Bool ret;
+ efl_access_object_attributes_clear(eo_item);
- ELM_WIDGET_CHECK(obj);
+ // TIZEN_ONLY(20150709) : atspi relations api
+ if (item->atspi_custom_relations)
+ efl_access_relation_set_free(&item->atspi_custom_relations);
+ //
- ret = EINA_FALSE;
+ //TIZEN_ONLY(20150731) : add i18n support for name and description
+ if (item->atspi_translation_domain)
+ eina_stringshare_del(item->atspi_translation_domain);
+ ///
- ret = efl_ui_widget_on_access_activate(obj, act);
+ //TIZEN_ONLY(20150713) : add widget_item name setter
+ if (item->name)
+ eina_stringshare_del(item->name);
+ //
- if (ret) return;
+ /***********************************************************************************
+ * TIZEN_ONLY_FEATURE: apply Tizen's color_class features. *
+ ***********************************************************************************/
+ if (item->color_classes)
+ ELM_SAFE_FREE(item->color_classes, eina_hash_free);
+ /*******
+ * END *
+ *******/
- parent = elm_widget_parent_get(obj);
- if (parent)
- elm_widget_activate(parent, act);
+ EINA_MAGIC_SET(item, EINA_MAGIC_NONE);
- return;
+ efl_destructor(efl_super(eo_item, ELM_WIDGET_ITEM_CLASS));
}
/**
* @internal
*
- * Sets the widget and child widget's Evas_Display_Mode.
+ * Releases widget item memory, calling back item_del_pre_hook() and
+ * item_del_cb() if they exist.
*
- * @param obj The widget.
- * @param dispmode Evas_Display_Mode to set widget's mode.
+ * @param item a valid #Elm_Widget_Item to be deleted.
*
- * Widgets are resized by several reasons.
- * Evas_Display_Mode can help for widgets to get one more reason of resize.
- * For example, elm conform widget resizes it's contents when keypad state changed.
- * After keypad showing, conform widget can change child's Evas_Display_Mode.
- * @ingroup Widget
- */
-/* Legacy only */
-EAPI void
-elm_widget_display_mode_set(Evas_Object *obj, Evas_Display_Mode dispmode)
-{
- Evas_Display_Mode prev_dispmode;
- Evas_Object *child;
- Eina_List *l;
-
- API_ENTRY return;
- prev_dispmode = evas_object_size_hint_display_mode_get(obj);
-
- if ((prev_dispmode == dispmode) ||
- (prev_dispmode == EVAS_DISPLAY_MODE_DONT_CHANGE)) return;
-
- evas_object_size_hint_display_mode_set(obj, dispmode);
-
- EINA_LIST_FOREACH (sd->subobjs, l, child)
- {
- if (elm_widget_is(child))
- elm_widget_display_mode_set(child, dispmode);
- }
-}
-
+ * If there is an Elm_Widget_Item::del_cb, then it will be called prior
+ * to memory release. Note that elm_widget_item_pre_notify_del() calls
+ * this function and then unset it, thus being useful for 2 step
+ * cleanup whenever the del_cb may use any of the data that must be
+ * deleted from item.
+ *
+ * The Elm_Widget_Item::view will be deleted (evas_object_del()) if it
+ * is presented!
+ *
+ * Note that if item_del_pre_hook() returns @c EINA_TRUE, item free will be
+ * deferred, or item will be freed here if it returns @c EINA_FALSE.
+ *
+ * @see elm_widget_item_del() convenience macro.
+ * @ingroup Widget
+ */
EOLIAN static void
-_efl_ui_widget_orientation_mode_set(Eo *obj, Elm_Widget_Smart_Data *sd, Efl_Ui_Widget_Orientation_Mode mode)
+_elm_widget_item_efl_object_invalidate(Eo *eo_item, Elm_Widget_Item_Data *item)
{
- int rotation = -1;
+ Evas_Object *view;
- if (mode != EFL_UI_WIDGET_ORIENTATION_MODE_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) rotation = 0;
- else rotation = sd_parent->orient_mode;
- }
- efl_ui_widget_on_orientation_update(obj, rotation);
-}
+ //Widget item delete callback
+ elm_wdg_item_del_pre(item->eo_obj);
-EOLIAN static Efl_Ui_Widget_Orientation_Mode
-_efl_ui_widget_orientation_mode_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
-{
- if (sd->orient_mode == -1) return EFL_UI_WIDGET_ORIENTATION_MODE_DISABLED;
- else return EFL_UI_WIDGET_ORIENTATION_MODE_DEFAULT;
+ view = item->view;
+ if (item->view) efl_wref_del(item->view, &item->view);
+ // FIXME: Is view an Efl.Ui or a legacy object ?
+ evas_object_del(view);
+ item->view = NULL;
+
+ efl_invalidate(efl_super(eo_item, ELM_WIDGET_ITEM_CLASS));
}
EOLIAN static void
-_efl_ui_widget_on_orientation_update(Eo *obj, Elm_Widget_Smart_Data *sd, int orient_mode)
+_elm_widget_item_del_pre(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item EINA_UNUSED)
{
- Evas_Object *child;
- Eina_List *l;
-
- sd->orient_mode = orient_mode;
-
- EINA_LIST_FOREACH (sd->subobjs, l, child)
- {
- if (elm_widget_is(child))
- efl_ui_widget_on_orientation_update(child, orient_mode);
- }
-
- if (orient_mode != -1)
- {
- char buf[128];
-
- if (elm_widget_is_legacy(obj))
- {
- snprintf(buf, sizeof(buf), "elm,state,orient,%d", orient_mode);
- elm_widget_signal_emit(obj, buf, "elm");
- }
- else
- {
- snprintf(buf, sizeof(buf), "efl,state,orient,%d", orient_mode);
- elm_widget_signal_emit(obj, buf, "efl");
- }
- }
}
/**
* @internal
*
- * Returns the widget's focus move policy.
+ * Notify object will be deleted without actually deleting it.
*
- * @param obj The widget.
- * @return focus move policy of the object.
+ * This function will callback Elm_Widget_Item::del_cb if it is set
+ * and then unset it so it is not called twice (ie: from
+ * elm_widget_item_del()).
*
- **/
-EOLIAN static Elm_Focus_Move_Policy
-_efl_ui_widget_focus_move_policy_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
+ * @param item a valid #Elm_Widget_Item to be notified
+ * @see elm_widget_item_pre_notify_del() convenience macro.
+ * @ingroup Widget
+ */
+EOLIAN static void
+_elm_widget_item_pre_notify_del(Eo *eo_item, Elm_Widget_Item_Data *item)
{
- return sd->focus_move_policy;
+ ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
+ if (!item->del_func) return;
+ item->del_func((void *)WIDGET_ITEM_DATA_GET(eo_item), item->widget, item->eo_obj);
+ item->del_func = NULL;
}
/**
* @internal
*
- * Sets the widget's focus move policy.
+ * Set the function to notify when item is being deleted.
*
- * @param obj The widget.
- * @param policy Elm_Focus_Move_Policy to set object's focus move policy.
+ * This function will complain if there was a callback set already,
+ * however it will set the new one.
+ *
+ * The callback will be called from elm_widget_item_pre_notify_del()
+ * or elm_widget_item_del() will be called with:
+ * - data: the Elm_Widget_Item::data value.
+ * - obj: the Elm_Widget_Item::widget evas object.
+ * - event_info: the item being deleted.
+ *
+ * @param item a valid #Elm_Widget_Item to be notified
+ * @see elm_widget_item_del_cb_set() convenience macro.
+ * @ingroup Widget
*/
-
EOLIAN static void
-_efl_ui_widget_focus_move_policy_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, Elm_Focus_Move_Policy policy)
+_elm_widget_item_del_cb_set(Eo *eo_item EINA_UNUSED,
+ Elm_Widget_Item_Data *item,
+ Evas_Smart_Cb func)
{
- if (sd->focus_move_policy == policy) return;
- sd->focus_move_policy = policy;
-}
+ ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
+ ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
-/**
- * Returns the widget's focus_move_policy mode setting.
- *
- * @param obj The widget.
- * @return focus_move_policy mode setting of the object.
- *
- **/
-EOLIAN static Eina_Bool
-_efl_ui_widget_focus_move_policy_automatic_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
-{
- return sd->focus_move_policy_auto_mode;
+ if ((item->del_func) && (item->del_func != func))
+ WRN("You're replacing a previously set del_cb %p of item %p with %p",
+ item->del_func, item->eo_obj, func);
+
+ item->del_func = func;
}
/**
* @internal
*
- * Sets the widget's focus_move_policy mode setting.
- * When widget in automatic mode, it follows the system focus_move_policy mode set by
- * elm_config_focus_move_policy_set().
- * @param obj The widget.
- * @param automatic EINA_TRUE for auto focus_move_policy mode. EINA_FALSE for manual.
+ * Get owner widget of this item.
+ *
+ * @param item a valid #Elm_Widget_Item to get data from.
+ * @return owner widget of this item.
+ * @ingroup Widget
*/
-EOLIAN static void
-_efl_ui_widget_focus_move_policy_automatic_set(Eo *obj, Elm_Widget_Smart_Data *sd, Eina_Bool automatic)
+EOLIAN static Evas_Object *
+_elm_widget_item_widget_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
{
- if (sd->focus_move_policy_auto_mode != automatic)
- {
- sd->focus_move_policy_auto_mode = automatic;
+ ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
+ ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item, NULL);
- if (automatic)
- {
- efl_ui_widget_focus_move_policy_set(obj, elm_config_focus_move_policy_get());
- }
- }
+ return item->widget;
}
-/**
- * @internal
- *
- * Sets the klass name of a widget.
- * @param obj The widget.
- * @param name Name of the klass to use.
- * @return Whether the name was different and thus replaced.
- */
EAPI Eina_Bool
-elm_widget_theme_klass_set(Evas_Object *obj, const char *name)
+_elm_widget_onscreen_is(const Evas_Object *widget)
{
- Elm_Widget_Smart_Data *pd = efl_data_scope_safe_get(obj, MY_CLASS);
- if (!pd) return EINA_FALSE;
+ Evas_Object *parent = (Evas_Object *)widget;
+ Eina_Rectangle r1, r2;
- return eina_stringshare_replace(&(pd->klass), name);
-}
+ Evas *evas = evas_object_evas_get(widget);
+ if (!evas) return EINA_FALSE;
-/**
- * @internal
- *
- * Gets the klass name of a widget.
- * @param obj The widget.
- * @return The current klass name of internal canvas object.
- */
-EAPI const char *
-elm_widget_theme_klass_get(const Evas_Object *obj)
-{
- Elm_Widget_Smart_Data *pd = efl_data_scope_safe_get(obj, MY_CLASS);
- if (!pd) return NULL;
+ evas_object_geometry_get(widget, &r1.x, &r1.y, &r1.w, &r1.h);
+ if (eina_rectangle_is_empty(&r1))
+ return EINA_FALSE;
- return (const char *)pd->klass;
+ // window does not have to check viewport and geometry
+ if (efl_isa(widget, EFL_UI_WIN_CLASS))
+ return EINA_TRUE;
+
+ // check if on canvas
+ evas_output_viewport_get(evas, &r2.x, &r2.y, &r2.w, &r2.h);
+ if (!eina_rectangles_intersect(&r1, &r2))
+ return EINA_FALSE;
+
+ // check if inside scrollable parent viewport
+ do {
+ parent = elm_widget_parent_get(parent);
+ if (parent && !evas_object_visible_get(parent))
+ return EINA_FALSE;
+ if (parent && efl_isa(parent, ELM_INTERFACE_SCROLLABLE_MIXIN))
+ {
+ evas_object_geometry_get(parent, &r2.x, &r2.y, &r2.w, &r2.h);
+ if (!eina_rectangles_intersect(&r1, &r2))
+ return EINA_FALSE;
+ }
+ } while (parent && (parent != elm_widget_top_get(widget)));
+
+ return EINA_TRUE;
}
-/**
- * @internal
- *
- * Sets the element name of a widget.
- *
- * @param obj The widget.
- * @param name Name of the element to use.
- * @return Whether the name was different and thus replaced.
- */
EAPI Eina_Bool
-elm_widget_theme_element_set(Evas_Object *obj, const char *name)
+_elm_widget_item_onscreen_is(const Elm_Object_Item *item)
{
- Elm_Widget_Smart_Data *pd = efl_data_scope_safe_get(obj, MY_CLASS);
- if (!pd) return EINA_FALSE;
+ Eina_Rectangle r1, r2;
+ Elm_Widget_Item_Data *id = efl_data_scope_get(item, ELM_WIDGET_ITEM_CLASS);
+ if (!id || !id->view) return EINA_FALSE;
- if (eina_streq(name, "base"))
- name = NULL;
+ if (!evas_object_visible_get(id->view))
+ return EINA_FALSE;
- return eina_stringshare_replace(&(pd->group), name);
-}
+ if (!_elm_widget_onscreen_is(id->widget))
+ return EINA_FALSE;
-/**
- * @internal
- *
- * Gets the element name of a widget.
- * @param obj The widget.
- * @return The current element name of internal canvas object.
- */
-EAPI const char *
-elm_widget_theme_element_get(const Evas_Object *obj)
-{
- Elm_Widget_Smart_Data *pd = efl_data_scope_safe_get(obj, MY_CLASS);
- if (!pd) return NULL;
+ evas_object_geometry_get(id->view, &r1.x, &r1.y, &r1.w, &r1.h);
+ if (eina_rectangle_is_empty(&r1))
+ return EINA_FALSE;
- return (const char *)pd->group;
+ evas_object_geometry_get(id->widget, &r2.x, &r2.y, &r2.w, &r2.h);
+ if (!eina_rectangles_intersect(&r1, &r2))
+ return EINA_FALSE;
+
+ return EINA_TRUE;
}
-/**
- * @internal
- *
- * Sets the style name of a widget.
- *
- * @param obj The widget.
- * @param name Name of the style to use.
- * @return Whether the name was different and thus replaced.
- */
-EAPI Eina_Bool
-elm_widget_theme_style_set(Evas_Object *obj, const char *name)
+const char*
+_elm_widget_accessible_plain_name_get(const Evas_Object *obj, const char* name)
{
- Elm_Widget_Smart_Data *pd = efl_data_scope_safe_get(obj, MY_CLASS);
- if (!pd) return EINA_FALSE;
+ char *accessible_plain_name;
- if (eina_streq(name, "default"))
- name = NULL;
+ API_ENTRY return NULL;
- return eina_stringshare_replace(&(pd->style), name);
+ accessible_plain_name = _elm_util_mkup_to_text(name);
+ eina_stringshare_del(sd->accessible_name);
+ sd->accessible_name = eina_stringshare_add(accessible_plain_name);
+ free(accessible_plain_name);
+ return sd->accessible_name;
}
-/**
- * @internal
- *
- * Gets the style name of a widget.
- * @param obj The widget.
- * @return The current style name of internal canvas object.
- */
-EAPI const char *
-elm_widget_theme_style_get(const Evas_Object *obj)
+const char*
+_elm_widget_item_accessible_plain_name_get(const Elm_Object_Item *item, const char* name)
{
- Elm_Widget_Smart_Data *pd = efl_data_scope_safe_get(obj, MY_CLASS);
- if (!pd) return NULL;
+ char *accessible_plain_name;
- return (const char *)pd->style;
+ Elm_Widget_Item_Data *id = efl_data_scope_get(item, ELM_WIDGET_ITEM_CLASS);
+ if (!id) return NULL;
+
+ accessible_plain_name = _elm_util_mkup_to_text(name);
+ eina_stringshare_del(id->accessible_name);
+ id->accessible_name = eina_stringshare_add(accessible_plain_name);
+ free(accessible_plain_name);
+ return id->accessible_name;
}
-/**
- * @internal
- *
- * Register sub object as a group of a widget and re-apply its theme.
- * @param obj The widget.
- * @param component A sub object to be added as an element of the widget.
- * @param name An element name of sub object.
- * @return Whether the style was successfully applied or not.
- */
-EAPI Efl_Ui_Theme_Apply_Result
-elm_widget_element_update(Evas_Object *obj, Evas_Object *component, const char *name)
+EOLIAN static Efl_Access_State_Set
+_elm_widget_item_efl_access_object_state_set_get(const Eo *eo_item, Elm_Widget_Item_Data *item)
{
- Efl_Ui_Theme_Apply_Result ret = EFL_UI_THEME_APPLY_RESULT_SUCCESS;
- Eina_Bool changed = EINA_FALSE;
- const char *obj_group;
- Eina_Stringshare *group;
+ Efl_Access_State_Set states = 0;
- obj_group = elm_widget_theme_element_get(obj);
- if (!obj_group)
- group = eina_stringshare_add(name);
- else
- group = eina_stringshare_printf("%s/%s", elm_widget_theme_element_get(obj), name);
- if (efl_isa(component, EFL_UI_WIDGET_CLASS))
+ // TIZEN_ONLY(20171114) Accessibility Highlight Frame added
+ // //TIZEN_ONLY(20171108): bring HIGHLIGHT related changes
+ // Evas_Object *win = elm_widget_top_get(item->widget);
+ // if (win && efl_isa(win, EFL_UI_WIN_CLASS))
+ // {
+ // if (_elm_win_accessibility_highlight_get(win) == item->view)
+ // STATE_TYPE_SET(states, ELM_ATSPI_STATE_HIGHLIGHTED);
+ // }
+ // STATE_TYPE_SET(states, ELM_ATSPI_STATE_HIGHLIGHTABLE);
+ // //
+ //
+
+ STATE_TYPE_SET(states, EFL_ACCESS_STATE_FOCUSABLE);
+
+ if (elm_object_item_focus_get(eo_item))
+ STATE_TYPE_SET(states, EFL_ACCESS_STATE_FOCUSED);
+ if (!elm_object_item_disabled_get(eo_item))
{
- changed |= elm_widget_theme_klass_set(component, elm_widget_theme_klass_get(obj));
- changed |= elm_widget_theme_element_set(component, (const char *)group);
- changed |= elm_widget_theme_style_set(component, elm_widget_theme_style_get(obj));
- if (changed)
- ret = efl_ui_widget_theme_apply(component);
+ STATE_TYPE_SET(states, EFL_ACCESS_STATE_ENABLED);
+ STATE_TYPE_SET(states, EFL_ACCESS_STATE_SENSITIVE);
}
+ if (_elm_widget_item_onscreen_is(eo_item))
+ STATE_TYPE_SET(states, EFL_ACCESS_STATE_SHOWING);
+
+ //TIZEN_ONLY(20170207) : [ATSPI] enhance expose highlight information on atspi
+ /* unrealized genlist item does not have item->view,
+ and item cannot change its visibility, only widget can change the visibility */
+ if (evas_object_visible_get(item->widget))
+ STATE_TYPE_SET(states, EFL_ACCESS_STATE_VISIBLE);
+ //
+
+ //TIZEN_ONLY(20170717) : expose highlight information on atspi
+ if (_elm_widget_item_highlightable(eo_item) && _accessible_object_on_scroll_is(item->view))
+ STATE_TYPE_SET(states, EFL_ACCESS_STATE_HIGHLIGHTABLE);
else
- {
- ret = elm_widget_theme_object_set(obj, component,
- elm_widget_theme_klass_get(obj),
- (const char *)group,
- elm_widget_theme_style_get(obj));
- }
- eina_stringshare_del(group);
+ STATE_TYPE_UNSET(states, EFL_ACCESS_STATE_HIGHLIGHTABLE);
- return ret;
+ if (_elm_object_accessibility_currently_highlighted_get() == (void*)item->eo_obj)
+ STATE_TYPE_SET(states, EFL_ACCESS_STATE_HIGHLIGHTED);
+ //
+ return states;
}
-static void
-_track_obj_del(void *data, Evas *e, Evas_Object *obj, void *event_info);
-
-static void
-_track_obj_update(Evas_Object *track, Evas_Object *obj)
+EAPI void
+elm_object_item_data_set(Elm_Object_Item *it, void *data)
{
- //Geometry
- Evas_Coord x, y, w, h;
- evas_object_geometry_get(obj, &x, &y, &w, &h);
- evas_object_move(track, x, y);
- evas_object_resize(track, w, h);
-
- //Visibility
- if (evas_object_visible_get(obj)) evas_object_show(track);
- else evas_object_hide(track);
+ WIDGET_ITEM_DATA_SET(it, data);
}
-static void
-_track_obj_view_update(void *data, const Efl_Event *event)
+EAPI void *
+elm_object_item_data_get(const Elm_Object_Item *it)
{
- Elm_Widget_Item_Data *item = data;
- _track_obj_update(item->track_obj, event->object);
+ return (void *) WIDGET_ITEM_DATA_GET(it);
}
-static void
-_track_obj_view_del(void *data, const Efl_Event *event);
-
-EFL_CALLBACKS_ARRAY_DEFINE(tracker_callbacks,
- { EFL_GFX_ENTITY_EVENT_RESIZE, _track_obj_view_update },
- { EFL_GFX_ENTITY_EVENT_MOVE, _track_obj_view_update },
- { EFL_GFX_ENTITY_EVENT_SHOW, _track_obj_view_update },
- { EFL_GFX_ENTITY_EVENT_HIDE, _track_obj_view_update },
- { EFL_EVENT_DEL, _track_obj_view_del });
-
-static void
-_track_obj_view_del(void *data, const Efl_Event *event EINA_UNUSED)
+EOLIAN static void
+_elm_widget_item_disabled_set(Eo *eo_item EINA_UNUSED,
+ Elm_Widget_Item_Data *item,
+ Eina_Bool disabled)
{
- Elm_Widget_Item_Data *item = data;
-
- while (evas_object_ref_get(item->track_obj) > 0)
- evas_object_unref(item->track_obj);
+ ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
+ ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
- evas_object_event_callback_del(item->track_obj, EVAS_CALLBACK_DEL,
- _track_obj_del);
- evas_object_del(item->track_obj);
- item->track_obj = NULL;
+ if (item->disabled == disabled) return;
+ item->disabled = !!disabled;
+ elm_wdg_item_disable(item->eo_obj);
}
-static void
-_track_obj_del(void *data, Evas *e EINA_UNUSED,
- Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
+EOLIAN static Eina_Bool
+_elm_widget_item_disabled_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
{
- Elm_Widget_Item_Data *item = data;
- item->track_obj = NULL;
-
- if (!item->view) return;
-
- efl_event_callback_array_del(item->view, tracker_callbacks(), item);
+ ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, EINA_FALSE);
+ return item->disabled;
}
-static void
-_elm_widget_item_signal_cb(void *data, Evas_Object *obj EINA_UNUSED, const char *emission,
- const char *source)
+EOLIAN static void
+_elm_widget_item_style_set(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item, const char *style)
{
- Elm_Widget_Item_Signal_Data *wisd = data;
- wisd->func(wisd->data, wisd->item, emission, source);
+ eina_stringshare_replace(&item->style, style);
}
-static void *
-_elm_widget_item_signal_callback_list_get(Elm_Widget_Item_Data *item, Eina_List *position)
+EOLIAN static const char *
+_elm_widget_item_style_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
{
- Elm_Widget_Item_Signal_Data *wisd = eina_list_data_get(position);
- void *data;
-
- item->signals = eina_list_remove_list(item->signals, position);
- data = wisd->data;
-
- if (_elm_widget_is(item->view))
- elm_object_signal_callback_del(item->view,
- wisd->emission, wisd->source,
- _elm_widget_item_signal_cb);
- else if (efl_isa(item->view, EFL_CANVAS_LAYOUT_CLASS))
- edje_object_signal_callback_del_full(item->view,
- wisd->emission, wisd->source,
- _elm_widget_item_signal_cb, wisd);
-
- eina_stringshare_del(wisd->emission);
- eina_stringshare_del(wisd->source);
- free(wisd);
-
- return data;
+ return item->style;
}
-#define ERR_NOT_SUPPORTED(item, method) ERR("%s does not support %s API.", elm_widget_type_get(item->widget), method);
+EOLIAN static void
+_elm_widget_item_disable(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item EINA_UNUSED)
+{
+}
-static void
-_efl_del_cb(void *data EINA_UNUSED, const Efl_Event *event)
+EOLIAN static void
+_elm_widget_item_item_focus_set(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item, Eina_Bool focused EINA_UNUSED)
{
- Elm_Widget_Item_Data *item = efl_data_scope_get(event->object, ELM_WIDGET_ITEM_CLASS);
- ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
- if (item->del_func)
- item->del_func((void *) WIDGET_ITEM_DATA_GET(event->object), item->widget, item->eo_obj);
+ ERR_NOT_SUPPORTED(item, "elm_object_item_focus_set");
}
-/**
- * @internal
- *
- * Allocate a new Elm_Widget_Item-derived structure.
- *
- * The goal of this structure is to provide common ground for actions
- * that a widget item have, such as the owner widget, callback to
- * notify deletion, data pointer and maybe more.
- *
- * @param widget the owner widget that holds this item, must be an elm_widget!
- * @param alloc_size any number greater than sizeof(Elm_Widget_Item) that will
- * be used to allocate memory.
- *
- * @return allocated memory that is already zeroed out, or NULL on errors.
- *
- * @see elm_widget_item_new() convenience macro.
- * @see elm_widget_item_del() to release memory.
- * @ingroup Widget
- */
-EOLIAN static Eo *
-_elm_widget_item_efl_object_constructor(Eo *eo_item, Elm_Widget_Item_Data *item)
+EOLIAN static Eina_Bool
+_elm_widget_item_item_focus_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
{
- Evas_Object *widget;
- widget = efl_parent_get(eo_item);
+ ERR_NOT_SUPPORTED(item, "elm_object_item_focus_get");
+ return EINA_FALSE;
+}
- if (!_elm_widget_is(widget))
+EOLIAN static void
+_elm_widget_item_domain_translatable_part_text_set(Eo *eo_item EINA_UNUSED,
+ Elm_Widget_Item_Data *item,
+ const char *part,
+ const char *domain,
+ const char *label)
+{
+ ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
+ ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
+ Elm_Translate_String_Data *ts;
+
+ if (!label)
{
- ERR("Failed");
- return NULL;
+ _part_text_translatable_set(&item->translate_strings, part, EINA_FALSE,
+ EINA_FALSE);
}
+ else
+ {
+ ts = _part_text_translatable_set(&item->translate_strings, part,
+ EINA_TRUE, EINA_FALSE);
+ if (!ts) return;
+ if (!ts->string) ts->string = eina_stringshare_add(label);
+ else eina_stringshare_replace(&ts->string, label);
+ if (!ts->domain) ts->domain = eina_stringshare_add(domain);
+ else eina_stringshare_replace(&ts->domain, domain);
+#ifdef HAVE_GETTEXT
+ if (label[0]) label = dgettext(domain, label);
+#endif
+ }
+ item->on_translate = EINA_TRUE;
+ elm_wdg_item_part_text_set(item->eo_obj, part, label);
+ item->on_translate = EINA_FALSE;
+}
- eo_item = efl_constructor(efl_super(eo_item, ELM_WIDGET_ITEM_CLASS));
-
- EINA_MAGIC_SET(item, ELM_WIDGET_ITEM_MAGIC);
-
- item->widget = widget;
- item->eo_obj = eo_item;
- //TIZEN_ONLY(20170717) : expose highlight information on atspi
- item->can_highlight = EINA_TRUE;
- //
- efl_event_callback_add(eo_item, EFL_EVENT_DEL, _efl_del_cb, NULL);
+EOLIAN static const char *
+_elm_widget_item_translatable_part_text_get(const Eo *eo_item EINA_UNUSED,
+ Elm_Widget_Item_Data *item,
+ const char *part)
+{
+ ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
+ ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item, NULL);
- return eo_item;
+ Elm_Translate_String_Data *ts;
+ ts = _translate_string_data_get(item->translate_strings, part);
+ if (ts) return ts->string;
+ return NULL;
}
EOLIAN static void
-_elm_widget_item_efl_object_destructor(Eo *eo_item, Elm_Widget_Item_Data *item)
+_elm_widget_item_domain_part_text_translatable_set(Eo *eo_item EINA_UNUSED,
+ Elm_Widget_Item_Data *item,
+ const char *part,
+ const char *domain,
+ Eina_Bool translatable)
{
+ ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
+ ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
Elm_Translate_String_Data *ts;
+ const char *text;
- ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
+ ts = _part_text_translatable_set(&item->translate_strings, part,
+ translatable, EINA_TRUE);
+ if (!ts) return;
+ if (!ts->domain) ts->domain = eina_stringshare_add(domain);
+ else eina_stringshare_replace(&ts->domain, domain);
- eina_stringshare_del(item->style);
- eina_stringshare_del(item->access_info);
- eina_stringshare_del(item->accessible_name);
+ text = elm_wdg_item_part_text_get(item->eo_obj, part);
- while (item->signals)
- _elm_widget_item_signal_callback_list_get(item, item->signals);
+ if (!text || !text[0]) return;
- while (item->translate_strings)
- {
- ts = EINA_INLIST_CONTAINER_GET(item->translate_strings,
- Elm_Translate_String_Data);
- eina_stringshare_del(ts->id);
- eina_stringshare_del(ts->domain);
- eina_stringshare_del(ts->string);
- item->translate_strings = eina_inlist_remove(item->translate_strings,
- item->translate_strings);
- free(ts);
- }
- eina_hash_free(item->labels);
+ if (!ts->string) ts->string = eina_stringshare_add(text);
- //TIZEN_ONLY : elm_widget_item: add at-spi name setter
- efl_access_object_description_set(eo_item, NULL);
- efl_access_object_i18n_name_set(eo_item, NULL);
+//Try to translate text since we don't know the text is already translated.
+#ifdef HAVE_GETTEXT
+ text = dgettext(domain, text);
+#endif
+ item->on_translate = EINA_TRUE;
+ elm_wdg_item_part_text_set(item->eo_obj, part, text);
+ item->on_translate = EINA_FALSE;
+}
- efl_access_object_description_cb_set(eo_item, NULL, NULL);
- efl_access_object_name_cb_set(eo_item, NULL, NULL);
- //
- //TIZEN_ONLY(20170405) Add gesture method to accessible interface
- efl_access_object_gesture_cb_set(eo_item, NULL, NULL);
- //
- //TIZEN_ONLY : elm_widget_item: add at-spi name setter
- efl_access_object_translation_domain_set(eo_item, NULL);
- efl_access_object_relationships_clear(eo_item);
- //
+EOLIAN static void
+_elm_widget_item_track_cancel(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
+{
+ ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
+ ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
- efl_access_object_attributes_clear(eo_item);
+ if (!item->track_obj) return;
- // TIZEN_ONLY(20150709) : atspi relations api
- if (item->atspi_custom_relations)
- efl_access_relation_set_free(&item->atspi_custom_relations);
- //
+ while (evas_object_ref_get(item->track_obj) > 0)
+ evas_object_unref(item->track_obj);
- //TIZEN_ONLY(20150731) : add i18n support for name and description
- if (item->atspi_translation_domain)
- eina_stringshare_del(item->atspi_translation_domain);
- ///
+ evas_object_del(item->track_obj);
+}
- //TIZEN_ONLY(20150713) : add widget_item name setter
- if (item->name)
- eina_stringshare_del(item->name);
- //
+EOLIAN static Evas_Object *
+_elm_widget_item_track(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
+{
+ ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
+ ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item, NULL);
- /***********************************************************************************
- * TIZEN_ONLY_FEATURE: apply Tizen's color_class features. *
- ***********************************************************************************/
- if (item->color_classes)
- ELM_SAFE_FREE(item->color_classes, eina_hash_free);
- /*******
- * END *
- *******/
+ if (item->track_obj)
+ {
+ evas_object_ref(item->track_obj);
+ return item->track_obj;
+ }
- EINA_MAGIC_SET(item, EINA_MAGIC_NONE);
+ if (!item->view)
+ {
+ WRN("view obj of the item(%p) is invalid. Please make sure the view obj is created!", item);
+ return NULL;
+ }
- efl_destructor(efl_super(eo_item, ELM_WIDGET_ITEM_CLASS));
+ Evas_Object *track =
+ evas_object_rectangle_add(evas_object_evas_get(item->widget));
+ evas_object_color_set(track, 0, 0, 0, 0);
+ evas_object_pass_events_set(track, EINA_TRUE);
+ _track_obj_update(track, item->view);
+ evas_object_event_callback_add(track, EVAS_CALLBACK_DEL, _track_obj_del,
+ item);
+
+ efl_event_callback_array_add(item->view, tracker_callbacks(), item);
+
+ evas_object_ref(track);
+
+ item->track_obj = track;
+
+ return track;
}
-/**
- * @internal
- *
- * Releases widget item memory, calling back item_del_pre_hook() and
- * item_del_cb() if they exist.
- *
- * @param item a valid #Elm_Widget_Item to be deleted.
- *
- * If there is an Elm_Widget_Item::del_cb, then it will be called prior
- * to memory release. Note that elm_widget_item_pre_notify_del() calls
- * this function and then unset it, thus being useful for 2 step
- * cleanup whenever the del_cb may use any of the data that must be
- * deleted from item.
- *
- * The Elm_Widget_Item::view will be deleted (evas_object_del()) if it
- * is presented!
- *
- * Note that if item_del_pre_hook() returns @c EINA_TRUE, item free will be
- * deferred, or item will be freed here if it returns @c EINA_FALSE.
- *
- * @see elm_widget_item_del() convenience macro.
- * @ingroup Widget
- */
EOLIAN static void
-_elm_widget_item_efl_object_invalidate(Eo *eo_item, Elm_Widget_Item_Data *item)
+_elm_widget_item_untrack(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
{
- Evas_Object *view;
-
- //Widget item delete callback
- elm_wdg_item_del_pre(item->eo_obj);
+ ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
+ ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
- view = item->view;
- if (item->view) efl_wref_del(item->view, &item->view);
- // FIXME: Is view an Efl.Ui or a legacy object ?
- evas_object_del(view);
- item->view = NULL;
+ if (!item->track_obj) return;
+ evas_object_unref(item->track_obj);
- efl_invalidate(efl_super(eo_item, ELM_WIDGET_ITEM_CLASS));
+ if (evas_object_ref_get(item->track_obj) == 0)
+ evas_object_del(item->track_obj);
}
-EOLIAN static void
-_elm_widget_item_del_pre(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item EINA_UNUSED)
+EOLIAN static int
+_elm_widget_item_track_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
{
+ ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, 0);
+ ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item, 0);
+
+ if (!item->track_obj) return 0;
+ return evas_object_ref_get(item->track_obj);
}
-/**
- * @internal
- *
- * Notify object will be deleted without actually deleting it.
- *
- * This function will callback Elm_Widget_Item::del_cb if it is set
- * and then unset it so it is not called twice (ie: from
- * elm_widget_item_del()).
- *
- * @param item a valid #Elm_Widget_Item to be notified
- * @see elm_widget_item_pre_notify_del() convenience macro.
- * @ingroup Widget
- */
-EOLIAN static void
-_elm_widget_item_pre_notify_del(Eo *eo_item, Elm_Widget_Item_Data *item)
+typedef struct _Elm_Widget_Item_Tooltip Elm_Widget_Item_Tooltip;
+
+struct _Elm_Widget_Item_Tooltip
{
- ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
- if (!item->del_func) return;
- item->del_func((void *)WIDGET_ITEM_DATA_GET(eo_item), item->widget, item->eo_obj);
- item->del_func = NULL;
+ Elm_Widget_Item_Data *item;
+ Elm_Tooltip_Item_Content_Cb func;
+ Evas_Smart_Cb del_cb;
+ const void *data;
+};
+
+static Evas_Object *
+_elm_widget_item_tooltip_label_create(void *data,
+ Evas_Object *obj EINA_UNUSED,
+ Evas_Object *tooltip,
+ void *item EINA_UNUSED)
+{
+ Evas_Object *label = elm_label_add(tooltip);
+ if (!label)
+ return NULL;
+ elm_object_style_set(label, "tooltip");
+ elm_object_text_set(label, data);
+ return label;
+}
+
+static Evas_Object *
+_elm_widget_item_tooltip_trans_label_create(void *data,
+ Evas_Object *obj EINA_UNUSED,
+ Evas_Object *tooltip,
+ void *item EINA_UNUSED)
+{
+ Evas_Object *label = elm_label_add(tooltip);
+ if (!label)
+ return NULL;
+ elm_object_style_set(label, "tooltip");
+ elm_object_translatable_text_set(label, data);
+ return label;
+}
+
+static void
+_elm_widget_item_tooltip_label_del_cb(void *data,
+ Evas_Object *obj EINA_UNUSED,
+ void *event_info EINA_UNUSED)
+{
+ eina_stringshare_del(data);
}
/**
* @internal
*
- * Set the function to notify when item is being deleted.
+ * Set the text to be shown in the widget item.
*
- * This function will complain if there was a callback set already,
- * however it will set the new one.
+ * @param item Target item
+ * @param text The text to set in the content
*
- * The callback will be called from elm_widget_item_pre_notify_del()
- * or elm_widget_item_del() will be called with:
- * - data: the Elm_Widget_Item::data value.
- * - obj: the Elm_Widget_Item::widget evas object.
- * - event_info: the item being deleted.
+ * Setup the text as tooltip to object. The item can have only one tooltip,
+ * so any previous tooltip data is removed.
*
- * @param item a valid #Elm_Widget_Item to be notified
- * @see elm_widget_item_del_cb_set() convenience macro.
* @ingroup Widget
*/
EOLIAN static void
-_elm_widget_item_del_cb_set(Eo *eo_item EINA_UNUSED,
- Elm_Widget_Item_Data *item,
- Evas_Smart_Cb func)
+_elm_widget_item_tooltip_text_set(Eo *eo_item EINA_UNUSED,
+ Elm_Widget_Item_Data *item EINA_UNUSED,
+ const char *text)
{
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
+ EINA_SAFETY_ON_NULL_RETURN(text);
- if ((item->del_func) && (item->del_func != func))
- WRN("You're replacing a previously set del_cb %p of item %p with %p",
- item->del_func, item->eo_obj, func);
+ text = eina_stringshare_add(text);
+ elm_wdg_item_tooltip_content_cb_set(item->eo_obj, _elm_widget_item_tooltip_label_create, text, _elm_widget_item_tooltip_label_del_cb);
+}
- item->del_func = func;
+EOLIAN static void
+_elm_widget_item_tooltip_translatable_text_set(Eo *eo_item EINA_UNUSED,
+ Elm_Widget_Item_Data *item EINA_UNUSED,
+ const char *text)
+{
+ ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
+ ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
+ EINA_SAFETY_ON_NULL_RETURN(text);
+
+ text = eina_stringshare_add(text);
+ elm_wdg_item_tooltip_content_cb_set(item->eo_obj, _elm_widget_item_tooltip_trans_label_create, text, _elm_widget_item_tooltip_label_del_cb);
+}
+
+static Evas_Object *
+_elm_widget_item_tooltip_create(void *data,
+ Evas_Object *obj,
+ Evas_Object *tooltip)
+{
+ Elm_Widget_Item_Tooltip *wit = data;
+ return wit->func((void *)wit->data, obj, tooltip, wit->item->eo_obj);
+}
+
+static void
+_elm_widget_item_tooltip_del_cb(void *data,
+ Evas_Object *obj,
+ void *event_info EINA_UNUSED)
+{
+ Elm_Widget_Item_Tooltip *wit = data;
+ if (wit->del_cb) wit->del_cb((void *)wit->data, obj, wit->item->eo_obj);
+ free(wit);
}
/**
* @internal
*
- * Get owner widget of this item.
+ * Set the content to be shown in the tooltip item
+ *
+ * Setup the tooltip to item. The item can have only one tooltip,
+ * so any previous tooltip data is removed. @p func(with @p data) will
+ * be called every time that need show the tooltip and it should
+ * return a valid Evas_Object. This object is then managed fully by
+ * tooltip system and is deleted when the tooltip is gone.
+ *
+ * @param item the widget item being attached a tooltip.
+ * @param func the function used to create the tooltip contents.
+ * @param data what to provide to @a func as callback data/context.
+ * @param del_cb called when data is not needed anymore, either when
+ * another callback replaces @func, the tooltip is unset with
+ * elm_widget_item_tooltip_unset() or the owner @a item
+ * dies. This callback receives as the first parameter the
+ * given @a data, and @c event_info is the item.
*
- * @param item a valid #Elm_Widget_Item to get data from.
- * @return owner widget of this item.
* @ingroup Widget
*/
-EOLIAN static Evas_Object *
-_elm_widget_item_widget_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
+EOLIAN static void
+_elm_widget_item_tooltip_content_cb_set(Eo *eo_item EINA_UNUSED,
+ Elm_Widget_Item_Data *item,
+ Elm_Tooltip_Item_Content_Cb func,
+ const void *data,
+ Evas_Smart_Cb del_cb)
{
- ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
- ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item, NULL);
+ Elm_Widget_Item_Tooltip *wit;
- return item->widget;
-}
+ ELM_WIDGET_ITEM_CHECK_OR_GOTO(item, error_noitem);
+ //ELM_WIDGET_ITEM_RETURN_IF_GOTO(item, error_noitem);
-EAPI Eina_Bool
-_elm_widget_onscreen_is(const Evas_Object *widget)
-{
- Evas_Object *parent = (Evas_Object *)widget;
- Eina_Rectangle r1, r2;
+ if (!func)
+ {
+ elm_wdg_item_tooltip_unset(item->eo_obj);
+ return;
+ }
- Evas *evas = evas_object_evas_get(widget);
- if (!evas) return EINA_FALSE;
+ wit = ELM_NEW(Elm_Widget_Item_Tooltip);
+ if (!wit) goto error;
+ wit->item = item;
+ wit->func = func;
+ wit->data = data;
+ wit->del_cb = del_cb;
- evas_object_geometry_get(widget, &r1.x, &r1.y, &r1.w, &r1.h);
- if (eina_rectangle_is_empty(&r1))
- return EINA_FALSE;
+ elm_object_sub_tooltip_content_cb_set
+ (item->view, item->widget, _elm_widget_item_tooltip_create, wit,
+ _elm_widget_item_tooltip_del_cb);
- // window does not have to check viewport and geometry
- if (efl_isa(widget, EFL_UI_WIN_CLASS))
- return EINA_TRUE;
+ return;
- // check if on canvas
- evas_output_viewport_get(evas, &r2.x, &r2.y, &r2.w, &r2.h);
- if (!eina_rectangles_intersect(&r1, &r2))
- return EINA_FALSE;
+error_noitem:
+ if (del_cb) del_cb((void *)data, NULL, item);
+ return;
+error:
+ if (del_cb) del_cb((void *)data, item->widget, item);
+}
- // check if inside scrollable parent viewport
- do {
- parent = elm_widget_parent_get(parent);
- if (parent && !evas_object_visible_get(parent))
- return EINA_FALSE;
- if (parent && efl_isa(parent, ELM_INTERFACE_SCROLLABLE_MIXIN))
- {
- evas_object_geometry_get(parent, &r2.x, &r2.y, &r2.w, &r2.h);
- if (!eina_rectangles_intersect(&r1, &r2))
- return EINA_FALSE;
- }
- } while (parent && (parent != elm_widget_top_get(widget)));
+/**
+ * @internal
+ *
+ * Unset tooltip from item
+ *
+ * @param item widget item to remove previously set tooltip.
+ *
+ * Remove tooltip from item. The callback provided as del_cb to
+ * elm_widget_item_tooltip_content_cb_set() will be called to notify
+ * it is not used anymore.
+ *
+ * @see elm_widget_item_tooltip_content_cb_set()
+ *
+ * @ingroup Widget
+ */
+EOLIAN static void
+_elm_widget_item_tooltip_unset(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
+{
+ ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
+ ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
- return EINA_TRUE;
+ elm_object_tooltip_unset(item->view);
}
-EAPI Eina_Bool
-_elm_widget_item_onscreen_is(const Elm_Object_Item *item)
+/**
+ * @internal
+ *
+ * Sets a different style for this item tooltip.
+ *
+ * @note before you set a style you should define a tooltip with
+ * elm_widget_item_tooltip_content_cb_set() or
+ * elm_widget_item_tooltip_text_set()
+ *
+ * @param item widget item with tooltip already set.
+ * @param style the theme style to use (default, transparent, ...)
+ *
+ * @ingroup Widget
+ */
+EOLIAN static void
+_elm_widget_item_tooltip_style_set(Eo *eo_item EINA_UNUSED,
+ Elm_Widget_Item_Data *item,
+ const char *style)
{
- Eina_Rectangle r1, r2;
- Elm_Widget_Item_Data *id = efl_data_scope_get(item, ELM_WIDGET_ITEM_CLASS);
- if (!id || !id->view) return EINA_FALSE;
-
- if (!evas_object_visible_get(id->view))
- return EINA_FALSE;
+ ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
+ ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
- if (!_elm_widget_onscreen_is(id->widget))
- return EINA_FALSE;
+ elm_object_tooltip_style_set(item->view, style);
+}
- evas_object_geometry_get(id->view, &r1.x, &r1.y, &r1.w, &r1.h);
- if (eina_rectangle_is_empty(&r1))
- return EINA_FALSE;
-
- evas_object_geometry_get(id->widget, &r2.x, &r2.y, &r2.w, &r2.h);
- if (!eina_rectangles_intersect(&r1, &r2))
- return EINA_FALSE;
-
- return EINA_TRUE;
-}
-
-const char*
-_elm_widget_accessible_plain_name_get(const Evas_Object *obj, const char* name)
-{
- char *accessible_plain_name;
-
- API_ENTRY return NULL;
-
- accessible_plain_name = _elm_util_mkup_to_text(name);
- eina_stringshare_del(sd->accessible_name);
- sd->accessible_name = eina_stringshare_add(accessible_plain_name);
- free(accessible_plain_name);
- return sd->accessible_name;
-}
-
-const char*
-_elm_widget_item_accessible_plain_name_get(const Elm_Object_Item *item, const char* name)
+EOLIAN static Eina_Bool
+_elm_widget_item_tooltip_window_mode_set(Eo *eo_item EINA_UNUSED,
+ Elm_Widget_Item_Data *item,
+ Eina_Bool disable)
{
- char *accessible_plain_name;
-
- Elm_Widget_Item_Data *id = efl_data_scope_get(item, ELM_WIDGET_ITEM_CLASS);
- if (!id) return NULL;
-
- accessible_plain_name = _elm_util_mkup_to_text(name);
- eina_stringshare_del(id->accessible_name);
- id->accessible_name = eina_stringshare_add(accessible_plain_name);
- free(accessible_plain_name);
- return id->accessible_name;
-}
+ ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, EINA_FALSE);
+ ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item, EINA_FALSE);
-//TIZEN_ONLY(20160929) : atspi: Improves how to find the can_highlight of the widget
-static Eina_Bool
-_elm_widget_can_highlight_get_by_class(Eo *obj)
-{
- if (efl_isa(obj, ELM_WIDGET_ITEM_CLASS))
- {
- Elm_Widget_Item_Data *id = efl_data_scope_get(obj, ELM_WIDGET_ITEM_CLASS);
- if (!id) return EINA_FALSE;
- if (!id->can_highlight) return EINA_FALSE;
- }
- else
- {
- Elm_Widget_Smart_Data *wd = efl_data_scope_get(obj, EFL_UI_WIDGET_CLASS);
- if (!wd) return EINA_FALSE;
- if (!wd->can_highlight) return EINA_FALSE;
- }
- return EINA_TRUE;
+ return elm_object_tooltip_window_mode_set(item->view, disable);
}
-//
-//TIZEN_ONLY(20161107): enhance elm_atspi_accessible_can_highlight_set to set can_hihglight property to its children
-EAPI Eina_Bool
-_elm_widget_item_highlightable(Elm_Object_Item *item)
+EOLIAN static Eina_Bool
+_elm_widget_item_tooltip_window_mode_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
{
- Eo *parent;
-
- Elm_Widget_Item_Data *id = efl_data_scope_get(item, ELM_WIDGET_ITEM_CLASS);
- if (!id) return EINA_FALSE;
- if (!id->can_highlight) return EINA_FALSE;
+ ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, EINA_FALSE);
+ ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item, EINA_FALSE);
- parent = efl_provider_find(efl_parent_get(item), EFL_ACCESS_OBJECT_MIXIN);
- while (parent && !efl_isa(parent, ELM_ATSPI_APP_OBJECT_CLASS))
- {
- //TIZEN_ONLY(20160929) : atspi: Improves how to find the can_highlight of the widget
- if (!_elm_widget_can_highlight_get_by_class(parent)) return EINA_FALSE;
- //
- parent = efl_provider_find(efl_parent_get(parent), EFL_ACCESS_OBJECT_MIXIN);
- }
- return EINA_TRUE;
+ return elm_object_tooltip_window_mode_get(item->view);
}
-//
-//TIZEN_ONLY(20170206): Add check the object is in the scroller content size
-Eina_Bool
-_accessible_object_on_scroll_is(Eo* obj)
+/**
+ * @internal
+ *
+ * Get the style for this item tooltip.
+ *
+ * @param item widget item with tooltip already set.
+ * @return style the theme style in use, defaults to "default". If the
+ * object does not have a tooltip set, then NULL is returned.
+ *
+ * @ingroup Widget
+ */
+EOLIAN static const char *
+_elm_widget_item_tooltip_style_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
{
- /* in case of genlist item, the item->view is NULL if item is unrealized.
- this function is used to check if obj could have HIGHLIGHTABLE or not.
- the unrealized genlist item should have HIGHLIGHTABLE state.
- so if obj is NULL return EINA_TRUE */
- if(!obj) return EINA_TRUE;
-
- Evas_Object *target = obj;
- Evas_Object *parent = NULL;
- Evas_Coord x, y, w, h, wx, wy, ww = 0, wh = 0, nx = 0, ny = 0;
-
- evas_object_geometry_get(target, &x, &y ,&w, &h);
-
- if (elm_widget_is(target))
- parent = elm_widget_parent_get(target);
- else
- parent = elm_widget_parent_widget_get(target);
-
- while (parent)
- {
- if (efl_isa(parent, ELM_INTERFACE_SCROLLABLE_MIXIN))
- {
- evas_object_geometry_get(parent, &wx, &wy, NULL, NULL);
- elm_interface_scrollable_content_size_get(parent, &ww, &wh);
- elm_interface_scrollable_content_pos_get(parent, &nx, &ny);
-
- /* widget implements scrollable interface but does not use scoller
- in this case, use widget geometry */
- if (ww == 0 || wh == 0)
- {
- INF("%s is zero sized scrollable content", efl_class_name_get(efl_class_get(parent)));
- evas_object_geometry_get(parent, NULL, NULL, &ww, &wh);
- }
-
- wx -= nx;
- wy -= ny;
-
- if (((wx < x) && (wx + ww < x)) || ((wx > x + w) && (wx + ww > x + w)) ||
- ((wy < y) && (wy + wh < y)) || ((wy > y + h) && (wy + wh > y + h)))
- return EINA_FALSE;
-
- break;
- }
- parent = elm_widget_parent_get(parent);
- }
+ ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
- return EINA_TRUE;
+ return elm_object_tooltip_style_get(item->view);
}
-//
-EOLIAN static Efl_Access_State_Set
-_elm_widget_item_efl_access_object_state_set_get(const Eo *eo_item, Elm_Widget_Item_Data *item)
+EOLIAN static void
+_elm_widget_item_cursor_set(Eo *eo_item EINA_UNUSED,
+ Elm_Widget_Item_Data *item,
+ const char *cursor)
{
- Efl_Access_State_Set states = 0;
-
- // TIZEN_ONLY(20171114) Accessibility Highlight Frame added
- // //TIZEN_ONLY(20171108): bring HIGHLIGHT related changes
- // Evas_Object *win = elm_widget_top_get(item->widget);
- // if (win && efl_isa(win, EFL_UI_WIN_CLASS))
- // {
- // if (_elm_win_accessibility_highlight_get(win) == item->view)
- // STATE_TYPE_SET(states, ELM_ATSPI_STATE_HIGHLIGHTED);
- // }
- // STATE_TYPE_SET(states, ELM_ATSPI_STATE_HIGHLIGHTABLE);
- // //
- //
-
- STATE_TYPE_SET(states, EFL_ACCESS_STATE_FOCUSABLE);
-
- if (elm_object_item_focus_get(eo_item))
- STATE_TYPE_SET(states, EFL_ACCESS_STATE_FOCUSED);
- if (!elm_object_item_disabled_get(eo_item))
- {
- STATE_TYPE_SET(states, EFL_ACCESS_STATE_ENABLED);
- STATE_TYPE_SET(states, EFL_ACCESS_STATE_SENSITIVE);
- }
- if (_elm_widget_item_onscreen_is(eo_item))
- STATE_TYPE_SET(states, EFL_ACCESS_STATE_SHOWING);
-
- //TIZEN_ONLY(20170207) : [ATSPI] enhance expose highlight information on atspi
- /* unrealized genlist item does not have item->view,
- and item cannot change its visibility, only widget can change the visibility */
- if (evas_object_visible_get(item->widget))
- STATE_TYPE_SET(states, EFL_ACCESS_STATE_VISIBLE);
- //
-
- //TIZEN_ONLY(20170717) : expose highlight information on atspi
- if (_elm_widget_item_highlightable(eo_item) && _accessible_object_on_scroll_is(item->view))
- STATE_TYPE_SET(states, EFL_ACCESS_STATE_HIGHLIGHTABLE);
- else
- STATE_TYPE_UNSET(states, EFL_ACCESS_STATE_HIGHLIGHTABLE);
-
- if (_elm_object_accessibility_currently_highlighted_get() == (void*)item->eo_obj)
- STATE_TYPE_SET(states, EFL_ACCESS_STATE_HIGHLIGHTED);
- //
- return states;
-}
+ ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
+ ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
-EAPI void
-elm_object_item_data_set(Elm_Object_Item *it, void *data)
-{
- WIDGET_ITEM_DATA_SET(it, data);
+ elm_object_sub_cursor_set(item->view, item->widget, cursor);
}
-EAPI void *
-elm_object_item_data_get(const Elm_Object_Item *it)
+EOLIAN static const char *
+_elm_widget_item_cursor_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
{
- return (void *) WIDGET_ITEM_DATA_GET(it);
+ ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
+ return elm_object_sub_cursor_get(item->view);
}
EOLIAN static void
-_elm_widget_item_disabled_set(Eo *eo_item EINA_UNUSED,
- Elm_Widget_Item_Data *item,
- Eina_Bool disabled)
+_elm_widget_item_cursor_unset(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
{
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
- if (item->disabled == disabled) return;
- item->disabled = !!disabled;
- elm_wdg_item_disable(item->eo_obj);
-}
-
-EOLIAN static Eina_Bool
-_elm_widget_item_disabled_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
-{
- ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, EINA_FALSE);
- return item->disabled;
+ elm_object_cursor_unset(item->view);
}
+/**
+ * @internal
+ *
+ * Sets a different style for this item cursor.
+ *
+ * @note before you set a style you should define a cursor with
+ * elm_widget_item_cursor_set()
+ *
+ * @param item widget item with cursor already set.
+ * @param style the theme style to use (default, transparent, ...)
+ *
+ * @ingroup Widget
+ */
EOLIAN static void
-_elm_widget_item_style_set(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item, const char *style)
+_elm_widget_item_cursor_style_set(Eo *eo_item EINA_UNUSED,
+ Elm_Widget_Item_Data *item,
+ const char *style)
{
- eina_stringshare_replace(&item->style, style);
-}
+ ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
+ ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
-EOLIAN static const char *
-_elm_widget_item_style_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
-{
- return item->style;
+ elm_object_sub_cursor_style_set(item->view, style);
}
-EOLIAN static void
-_elm_widget_item_disable(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item EINA_UNUSED)
+/**
+ * @internal
+ *
+ * Get the style for this item cursor.
+ *
+ * @param item widget item with cursor already set.
+ * @return style the theme style in use, defaults to "default". If the
+ * object does not have a cursor set, then NULL is returned.
+ *
+ * @ingroup Widget
+ */
+EOLIAN static const char *
+_elm_widget_item_cursor_style_get(const Eo *eo_item EINA_UNUSED,
+ Elm_Widget_Item_Data *item)
{
+ ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
+ return elm_object_sub_cursor_style_get(item->view);
}
+/**
+ * @internal
+ *
+ * Set if the cursor set should be searched on the theme or should use
+ * the provided by the engine, only.
+ *
+ * @note before you set if should look on theme you should define a cursor
+ * with elm_object_cursor_set(). By default it will only look for cursors
+ * provided by the engine.
+ *
+ * @param item widget item with cursor already set.
+ * @param engine_only boolean to define it cursors should be looked only
+ * between the provided by the engine or searched on widget's theme as well.
+ *
+ * @ingroup Widget
+ */
EOLIAN static void
-_elm_widget_item_item_focus_set(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item, Eina_Bool focused EINA_UNUSED)
+_elm_widget_item_cursor_engine_only_set(Eo *eo_item EINA_UNUSED,
+ Elm_Widget_Item_Data *item,
+ Eina_Bool engine_only)
{
- ERR_NOT_SUPPORTED(item, "elm_object_item_focus_set");
+ ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
+ ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
+
+ elm_object_sub_cursor_theme_search_enabled_set(item->view, !engine_only);
}
+/**
+ * @internal
+ *
+ * Get the cursor engine only usage for this item cursor.
+ *
+ * @param item widget item with cursor already set.
+ * @return engine_only boolean to define it cursors should be looked only
+ * between the provided by the engine or searched on widget's theme as well. If
+ * the object does not have a cursor set, then EINA_FALSE is returned.
+ *
+ * @ingroup Widget
+ */
EOLIAN static Eina_Bool
-_elm_widget_item_item_focus_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
+_elm_widget_item_cursor_engine_only_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
{
- ERR_NOT_SUPPORTED(item, "elm_object_item_focus_get");
- return EINA_FALSE;
+ ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, EINA_FALSE);
+ return !elm_object_sub_cursor_theme_search_enabled_get(item->view);
}
EOLIAN static void
-_elm_widget_item_domain_translatable_part_text_set(Eo *eo_item EINA_UNUSED,
- Elm_Widget_Item_Data *item,
- const char *part,
- const char *domain,
- const char *label)
+_elm_widget_item_part_content_set(Eo *eo_item EINA_UNUSED,
+ Elm_Widget_Item_Data *item,
+ const char *part EINA_UNUSED,
+ Evas_Object *content EINA_UNUSED)
{
- ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
- ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
- Elm_Translate_String_Data *ts;
-
- if (!label)
- {
- _part_text_translatable_set(&item->translate_strings, part, EINA_FALSE,
- EINA_FALSE);
- }
- else
- {
- ts = _part_text_translatable_set(&item->translate_strings, part,
- EINA_TRUE, EINA_FALSE);
- if (!ts) return;
- if (!ts->string) ts->string = eina_stringshare_add(label);
- else eina_stringshare_replace(&ts->string, label);
- if (!ts->domain) ts->domain = eina_stringshare_add(domain);
- else eina_stringshare_replace(&ts->domain, domain);
-#ifdef HAVE_GETTEXT
- if (label[0]) label = dgettext(domain, label);
-#endif
- }
- item->on_translate = EINA_TRUE;
- elm_wdg_item_part_text_set(item->eo_obj, part, label);
- item->on_translate = EINA_FALSE;
+ ERR_NOT_SUPPORTED(item, "elm_object_part_content_set()");
}
-EOLIAN static const char *
-_elm_widget_item_translatable_part_text_get(const Eo *eo_item EINA_UNUSED,
- Elm_Widget_Item_Data *item,
- const char *part)
+EOLIAN static Evas_Object *
+_elm_widget_item_part_content_get(const Eo *eo_item EINA_UNUSED,
+ Elm_Widget_Item_Data *item,
+ const char *part EINA_UNUSED)
{
- ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
- ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item, NULL);
+ ERR_NOT_SUPPORTED(item, "elm_object_part_content_get()");
+ return NULL;
+}
- Elm_Translate_String_Data *ts;
- ts = _translate_string_data_get(item->translate_strings, part);
- if (ts) return ts->string;
+EOLIAN static Evas_Object *
+_elm_widget_item_part_content_unset(Eo *eo_item EINA_UNUSED,
+ Elm_Widget_Item_Data *item,
+ const char *part EINA_UNUSED)
+{
+ ERR_NOT_SUPPORTED(item, "elm_object_part_content_unset()");
return NULL;
}
EOLIAN static void
-_elm_widget_item_domain_part_text_translatable_set(Eo *eo_item EINA_UNUSED,
- Elm_Widget_Item_Data *item,
- const char *part,
- const char *domain,
- Eina_Bool translatable)
+_elm_widget_item_part_text_set(Eo *eo_item EINA_UNUSED,
+ Elm_Widget_Item_Data *item,
+ const char *part EINA_UNUSED,
+ const char *label EINA_UNUSED)
{
- ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
- ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
- Elm_Translate_String_Data *ts;
- const char *text;
-
- ts = _part_text_translatable_set(&item->translate_strings, part,
- translatable, EINA_TRUE);
- if (!ts) return;
- if (!ts->domain) ts->domain = eina_stringshare_add(domain);
- else eina_stringshare_replace(&ts->domain, domain);
-
- text = elm_wdg_item_part_text_get(item->eo_obj, part);
-
- if (!text || !text[0]) return;
+ ERR_NOT_SUPPORTED(item, "elm_object_part_text_set()");
+}
- if (!ts->string) ts->string = eina_stringshare_add(text);
+EOLIAN static const char *
+_elm_widget_item_part_text_get(const Eo *eo_item EINA_UNUSED,
+ Elm_Widget_Item_Data *item,
+ const char *part EINA_UNUSED)
+{
+ ERR_NOT_SUPPORTED(item, "elm_object_part_text_get()");
+ return NULL;
+}
-//Try to translate text since we don't know the text is already translated.
-#ifdef HAVE_GETTEXT
- text = dgettext(domain, text);
-#endif
- item->on_translate = EINA_TRUE;
- elm_wdg_item_part_text_set(item->eo_obj, part, text);
- item->on_translate = EINA_FALSE;
+static void
+_elm_widget_item_part_text_custom_free(void *data)
+{
+ Elm_Label_Data *label;
+ label = data;
+ eina_stringshare_del(label->part);
+ eina_stringshare_del(label->text);
+ free(label);
}
EOLIAN static void
-_elm_widget_item_track_cancel(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
+_elm_widget_item_part_text_custom_set(Eo *eo_item EINA_UNUSED,
+ Elm_Widget_Item_Data *item,
+ const char *part,
+ const char *text)
{
+ Elm_Label_Data *label;
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
- if (!item->track_obj) return;
-
- while (evas_object_ref_get(item->track_obj) > 0)
- evas_object_unref(item->track_obj);
-
- evas_object_del(item->track_obj);
+ if (!item->labels)
+ item->labels =
+ eina_hash_stringshared_new(_elm_widget_item_part_text_custom_free);
+ label = eina_hash_find(item->labels, part);
+ if (!label)
+ {
+ label = malloc(sizeof(Elm_Label_Data));
+ if (!label)
+ {
+ ERR("Failed to allocate memory");
+ return;
+ }
+ label->part = eina_stringshare_add(part);
+ label->text = eina_stringshare_add(text);
+ eina_hash_add(item->labels, part, label);
+ }
+ else
+ eina_stringshare_replace(&label->text, text);
}
-EOLIAN static Evas_Object *
-_elm_widget_item_track(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
+EOLIAN static const char *
+_elm_widget_item_part_text_custom_get(const Eo *eo_item EINA_UNUSED,
+ Elm_Widget_Item_Data *item,
+ const char *part)
{
+ Elm_Label_Data *label;
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
- ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item, NULL);
-
- if (item->track_obj)
- {
- evas_object_ref(item->track_obj);
- return item->track_obj;
- }
-
- if (!item->view)
- {
- WRN("view obj of the item(%p) is invalid. Please make sure the view obj is created!", item);
- return NULL;
- }
-
- Evas_Object *track =
- evas_object_rectangle_add(evas_object_evas_get(item->widget));
- evas_object_color_set(track, 0, 0, 0, 0);
- evas_object_pass_events_set(track, EINA_TRUE);
- _track_obj_update(track, item->view);
- evas_object_event_callback_add(track, EVAS_CALLBACK_DEL, _track_obj_del,
- item);
-
- efl_event_callback_array_add(item->view, tracker_callbacks(), item);
+ label = eina_hash_find(item->labels, part);
+ return label ? label->text : NULL;
+}
- evas_object_ref(track);
+static Eina_Bool
+_elm_widget_item_part_text_custom_foreach(const Eina_Hash *labels EINA_UNUSED,
+ const void *key EINA_UNUSED,
+ void *data,
+ void *func_data)
+{
+ Elm_Label_Data *label;
+ Elm_Widget_Item_Data *item;
+ label = data;
+ item = func_data;
- item->track_obj = track;
+ elm_wdg_item_part_text_set(item->eo_obj, label->part, label->text);
- return track;
+ return EINA_TRUE;
}
EOLIAN static void
-_elm_widget_item_untrack(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
+_elm_widget_item_part_text_custom_update(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
{
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
-
- if (!item->track_obj) return;
- evas_object_unref(item->track_obj);
-
- if (evas_object_ref_get(item->track_obj) == 0)
- evas_object_del(item->track_obj);
+ if (item->labels)
+ eina_hash_foreach(item->labels,
+ _elm_widget_item_part_text_custom_foreach, item);
}
-EOLIAN static int
-_elm_widget_item_track_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
+EOLIAN static void
+_elm_widget_item_signal_emit(Eo *eo_item EINA_UNUSED,
+ Elm_Widget_Item_Data *item EINA_UNUSED,
+ const char *emission EINA_UNUSED,
+ const char *source EINA_UNUSED)
{
- ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, 0);
- ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item, 0);
- if (!item->track_obj) return 0;
- return evas_object_ref_get(item->track_obj);
}
-typedef struct _Elm_Widget_Item_Tooltip Elm_Widget_Item_Tooltip;
-
-struct _Elm_Widget_Item_Tooltip
+EOLIAN static void
+_elm_widget_item_signal_callback_add(Eo *eo_item,
+ Elm_Widget_Item_Data *item,
+ const char *emission,
+ const char *source,
+ Elm_Object_Item_Signal_Cb func,
+ void *data)
{
- Elm_Widget_Item_Data *item;
- Elm_Tooltip_Item_Content_Cb func;
- Evas_Smart_Cb del_cb;
- const void *data;
-};
+ ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
+ ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
+ EINA_SAFETY_ON_NULL_RETURN(func);
-static Evas_Object *
-_elm_widget_item_tooltip_label_create(void *data,
- Evas_Object *obj EINA_UNUSED,
- Evas_Object *tooltip,
- void *item EINA_UNUSED)
-{
- Evas_Object *label = elm_label_add(tooltip);
- if (!label)
- return NULL;
- elm_object_style_set(label, "tooltip");
- elm_object_text_set(label, data);
- return label;
-}
+ Elm_Widget_Item_Signal_Data *wisd;
-static Evas_Object *
-_elm_widget_item_tooltip_trans_label_create(void *data,
- Evas_Object *obj EINA_UNUSED,
- Evas_Object *tooltip,
- void *item EINA_UNUSED)
-{
- Evas_Object *label = elm_label_add(tooltip);
- if (!label)
- return NULL;
- elm_object_style_set(label, "tooltip");
- elm_object_translatable_text_set(label, data);
- return label;
+ wisd = malloc(sizeof(Elm_Widget_Item_Signal_Data));
+ if (!wisd) return;
+
+ wisd->item = eo_item;
+ wisd->func = (Elm_Widget_Item_Signal_Cb)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 (efl_isa(item->view, EFL_CANVAS_LAYOUT_CLASS))
+ 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!",
+ efl_class_name_get(efl_class_get(item->widget)));
+ free(wisd);
+ return;
+ }
+
+ item->signals = eina_list_append(item->signals, wisd);
}
-static void
-_elm_widget_item_tooltip_label_del_cb(void *data,
- Evas_Object *obj EINA_UNUSED,
- void *event_info EINA_UNUSED)
+EOLIAN static void *
+_elm_widget_item_signal_callback_del(Eo *eo_item EINA_UNUSED,
+ Elm_Widget_Item_Data *item,
+ const char *emission,
+ const char *source,
+ Elm_Object_Item_Signal_Cb func)
{
- eina_stringshare_del(data);
+ Elm_Widget_Item_Signal_Data *wisd;
+ Eina_List *l;
+
+ ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
+ ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item, NULL);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(func, NULL);
+
+ EINA_LIST_FOREACH(item->signals, l, wisd)
+ {
+ if ((wisd->func == (Elm_Widget_Item_Signal_Cb)func) &&
+ !strcmp(wisd->emission, emission) &&
+ !strcmp(wisd->source, source))
+ return _elm_widget_item_signal_callback_list_get(item, l);
+ }
+
+ return NULL;
}
-/**
- * @internal
- *
- * Set the text to be shown in the widget item.
- *
- * @param item Target item
- * @param text The text to set in the content
- *
- * Setup the text as tooltip to object. The item can have only one tooltip,
- * so any previous tooltip data is removed.
- *
- * @ingroup Widget
- */
+
+
EOLIAN static void
-_elm_widget_item_tooltip_text_set(Eo *eo_item EINA_UNUSED,
- Elm_Widget_Item_Data *item EINA_UNUSED,
- const char *text)
+_elm_widget_item_access_info_set(Eo *eo_item EINA_UNUSED,
+ Elm_Widget_Item_Data *item,
+ const char *txt)
{
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
- EINA_SAFETY_ON_NULL_RETURN(text);
- text = eina_stringshare_add(text);
- elm_wdg_item_tooltip_content_cb_set(item->eo_obj, _elm_widget_item_tooltip_label_create, text, _elm_widget_item_tooltip_label_del_cb);
+ eina_stringshare_del(item->access_info);
+ if (!txt) item->access_info = NULL;
+ else item->access_info = eina_stringshare_add(txt);
}
EOLIAN static void
-_elm_widget_item_tooltip_translatable_text_set(Eo *eo_item EINA_UNUSED,
- Elm_Widget_Item_Data *item EINA_UNUSED,
- const char *text)
+_elm_widget_item_translate(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
{
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
- EINA_SAFETY_ON_NULL_RETURN(text);
- text = eina_stringshare_add(text);
- elm_wdg_item_tooltip_content_cb_set(item->eo_obj, _elm_widget_item_tooltip_trans_label_create, text, _elm_widget_item_tooltip_label_del_cb);
+#ifdef HAVE_GETTEXT
+ Elm_Translate_String_Data *ts;
+ EINA_INLIST_FOREACH(item->translate_strings, ts)
+ {
+ if (!ts->string) continue;
+ const char *s = dgettext(ts->domain, ts->string);
+ item->on_translate = EINA_TRUE;
+ elm_wdg_item_part_text_set(item->eo_obj, ts->id, s);
+ item->on_translate = EINA_FALSE;
+ }
+#endif
}
-static Evas_Object *
-_elm_widget_item_tooltip_create(void *data,
- Evas_Object *obj,
- Evas_Object *tooltip)
+EOLIAN static void
+_elm_widget_item_access_order_set(Eo *eo_item EINA_UNUSED,
+ Elm_Widget_Item_Data *item,
+ Eina_List *objs)
{
- Elm_Widget_Item_Tooltip *wit = data;
- return wit->func((void *)wit->data, obj, tooltip, wit->item->eo_obj);
+ _elm_access_widget_item_access_order_set(item, objs);
}
-static void
-_elm_widget_item_tooltip_del_cb(void *data,
- Evas_Object *obj,
- void *event_info EINA_UNUSED)
+EOLIAN static const Eina_List *
+_elm_widget_item_access_order_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
{
- Elm_Widget_Item_Tooltip *wit = data;
- if (wit->del_cb) wit->del_cb((void *)wit->data, obj, wit->item->eo_obj);
- free(wit);
+ return _elm_access_widget_item_access_order_get(item);
}
-/**
- * @internal
- *
- * Set the content to be shown in the tooltip item
- *
- * Setup the tooltip to item. The item can have only one tooltip,
- * so any previous tooltip data is removed. @p func(with @p data) will
- * be called every time that need show the tooltip and it should
- * return a valid Evas_Object. This object is then managed fully by
- * tooltip system and is deleted when the tooltip is gone.
- *
- * @param item the widget item being attached a tooltip.
- * @param func the function used to create the tooltip contents.
- * @param data what to provide to @a func as callback data/context.
- * @param del_cb called when data is not needed anymore, either when
- * another callback replaces @func, the tooltip is unset with
- * elm_widget_item_tooltip_unset() or the owner @a item
- * dies. This callback receives as the first parameter the
- * given @a data, and @c event_info is the item.
- *
- * @ingroup Widget
- */
EOLIAN static void
-_elm_widget_item_tooltip_content_cb_set(Eo *eo_item EINA_UNUSED,
- Elm_Widget_Item_Data *item,
- Elm_Tooltip_Item_Content_Cb func,
- const void *data,
- Evas_Smart_Cb del_cb)
+_elm_widget_item_access_order_unset(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
{
- Elm_Widget_Item_Tooltip *wit;
+ _elm_access_widget_item_access_order_unset(item);
+}
- ELM_WIDGET_ITEM_CHECK_OR_GOTO(item, error_noitem);
- //ELM_WIDGET_ITEM_RETURN_IF_GOTO(item, error_noitem);
+EOLIAN static Evas_Object*
+_elm_widget_item_access_register(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
+{
+ _elm_access_widget_item_register(item);
+ return item->access_obj;
+}
- if (!func)
- {
- elm_wdg_item_tooltip_unset(item->eo_obj);
- return;
- }
+EOLIAN static void
+_elm_widget_item_access_unregister(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
+{
+ _elm_access_widget_item_unregister(item);
+}
- wit = ELM_NEW(Elm_Widget_Item_Tooltip);
- if (!wit) goto error;
- wit->item = item;
- wit->func = func;
- wit->data = data;
- wit->del_cb = del_cb;
+EOLIAN static Evas_Object*
+_elm_widget_item_access_object_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
+{
+ return item->access_obj;
+}
- elm_object_sub_tooltip_content_cb_set
- (item->view, item->widget, _elm_widget_item_tooltip_create, wit,
- _elm_widget_item_tooltip_del_cb);
+EOLIAN static Evas_Object *
+_elm_widget_item_focus_next_object_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item, Elm_Focus_Direction dir)
+{
+ Evas_Object *ret = NULL;
- return;
+ if (dir == ELM_FOCUS_PREVIOUS)
+ ret = item->focus_previous;
+ else if (dir == ELM_FOCUS_NEXT)
+ ret = item->focus_next;
+ else if (dir == ELM_FOCUS_UP)
+ ret = item->focus_up;
+ else if (dir == ELM_FOCUS_DOWN)
+ ret = item->focus_down;
+ else if (dir == ELM_FOCUS_RIGHT)
+ ret = item->focus_right;
+ else if (dir == ELM_FOCUS_LEFT)
+ ret = item->focus_left;
-error_noitem:
- if (del_cb) del_cb((void *)data, NULL, item);
- return;
-error:
- if (del_cb) del_cb((void *)data, item->widget, item);
+ return ret;
}
-/**
- * @internal
- *
- * Unset tooltip from item
- *
- * @param item widget item to remove previously set tooltip.
- *
- * Remove tooltip from item. The callback provided as del_cb to
- * elm_widget_item_tooltip_content_cb_set() will be called to notify
- * it is not used anymore.
- *
- * @see elm_widget_item_tooltip_content_cb_set()
- *
- * @ingroup Widget
- */
EOLIAN static void
-_elm_widget_item_tooltip_unset(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
+_elm_widget_item_focus_next_object_set(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item, Evas_Object *next, Elm_Focus_Direction dir)
{
- ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
- ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
-
- elm_object_tooltip_unset(item->view);
+ if (dir == ELM_FOCUS_PREVIOUS)
+ item->focus_previous = next;
+ else if (dir == ELM_FOCUS_NEXT)
+ item->focus_next = next;
+ else if (dir == ELM_FOCUS_UP)
+ item->focus_up = next;
+ else if (dir == ELM_FOCUS_DOWN)
+ item->focus_down = next;
+ else if (dir == ELM_FOCUS_RIGHT)
+ item->focus_right = next;
+ else if (dir == ELM_FOCUS_LEFT)
+ item->focus_left = next;
}
-/**
- * @internal
- *
- * Sets a different style for this item tooltip.
- *
- * @note before you set a style you should define a tooltip with
- * elm_widget_item_tooltip_content_cb_set() or
- * elm_widget_item_tooltip_text_set()
- *
- * @param item widget item with tooltip already set.
- * @param style the theme style to use (default, transparent, ...)
- *
- * @ingroup Widget
- */
-EOLIAN static void
-_elm_widget_item_tooltip_style_set(Eo *eo_item EINA_UNUSED,
- Elm_Widget_Item_Data *item,
- const char *style)
+EOLIAN static Elm_Object_Item*
+_elm_widget_item_focus_next_item_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item, Elm_Focus_Direction dir)
{
- ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
- ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
+ Elm_Object_Item *ret = NULL;
- elm_object_tooltip_style_set(item->view, style);
+ if (dir == ELM_FOCUS_PREVIOUS)
+ ret = item->item_focus_previous;
+ else if (dir == ELM_FOCUS_NEXT)
+ ret = item->item_focus_next;
+ else if (dir == ELM_FOCUS_UP)
+ ret = item->item_focus_up;
+ else if (dir == ELM_FOCUS_DOWN)
+ ret = item->item_focus_down;
+ else if (dir == ELM_FOCUS_RIGHT)
+ ret = item->item_focus_right;
+ else if (dir == ELM_FOCUS_LEFT)
+ ret = item->item_focus_left;
+
+ return ret;
}
-EOLIAN static Eina_Bool
-_elm_widget_item_tooltip_window_mode_set(Eo *eo_item EINA_UNUSED,
- Elm_Widget_Item_Data *item,
- Eina_Bool disable)
+EOLIAN static void
+_elm_widget_item_focus_next_item_set(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item, Elm_Object_Item *next_item, Elm_Focus_Direction dir)
{
- ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, EINA_FALSE);
- ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item, EINA_FALSE);
-
- return elm_object_tooltip_window_mode_set(item->view, disable);
+ if (dir == ELM_FOCUS_PREVIOUS)
+ item->item_focus_previous = next_item;
+ else if (dir == ELM_FOCUS_NEXT)
+ item->item_focus_next = next_item;
+ else if (dir == ELM_FOCUS_UP)
+ item->item_focus_up = next_item;
+ else if (dir == ELM_FOCUS_DOWN)
+ item->item_focus_down = next_item;
+ else if (dir == ELM_FOCUS_RIGHT)
+ item->item_focus_right = next_item;
+ else if (dir == ELM_FOCUS_LEFT)
+ item->item_focus_left = next_item;
}
-EOLIAN static Eina_Bool
-_elm_widget_item_tooltip_window_mode_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
+/* happy debug functions */
+#ifdef ELM_DEBUG
+static void
+_sub_obj_tree_dump(const Evas_Object *obj,
+ int lvl)
{
- ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, EINA_FALSE);
- ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item, EINA_FALSE);
+ int i;
- return elm_object_tooltip_window_mode_get(item->view);
+ for (i = 0; i < lvl * 3; i++)
+ putchar(' ');
+
+ if (_elm_widget_is(obj))
+ {
+ Eina_List *l;
+ INTERNAL_ENTRY;
+ DBG("+ %s(%p)\n",
+ elm_widget_type_get(obj),
+ obj);
+ EINA_LIST_FOREACH(sd->subobjs, l, obj)
+ _sub_obj_tree_dump(obj, lvl + 1);
+ }
+ else
+ DBG("+ %s(%p)\n", evas_object_type_get(obj), obj);
}
-/**
- * @internal
- *
- * Get the style for this item tooltip.
- *
- * @param item widget item with tooltip already set.
- * @return style the theme style in use, defaults to "default". If the
- * object does not have a tooltip set, then NULL is returned.
- *
- * @ingroup Widget
- */
-EOLIAN static const char *
-_elm_widget_item_tooltip_style_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
+static void
+_sub_obj_tree_dot_dump(const Evas_Object *obj,
+ FILE *output)
{
- ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
+ if (!_elm_widget_is(obj))
+ return;
+ INTERNAL_ENTRY;
- return elm_object_tooltip_style_get(item->view);
-}
+ Eina_Bool visible = evas_object_visible_get(obj);
+ Eina_Bool disabled = elm_widget_disabled_get(obj);
+ Eina_Bool focused = efl_ui_focus_object_focus_get(obj);
+ Eina_Bool can_focus = elm_widget_can_focus_get(obj);
-EOLIAN static void
-_elm_widget_item_cursor_set(Eo *eo_item EINA_UNUSED,
- Elm_Widget_Item_Data *item,
- const char *cursor)
-{
- ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
- ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
+ if (sd->parent_obj)
+ {
+ fprintf(output, "\"%p\" -- \"%p\" [ color=black", sd->parent_obj, obj);
- elm_object_sub_cursor_set(item->view, item->widget, cursor);
+ if (focused)
+ fprintf(output, ", style=bold");
+
+ if (!visible)
+ fprintf(output, ", color=gray28");
+
+ fprintf(output, " ];\n");
+ }
+
+ fprintf(output, "\"%p\" [ label = \"{%p|%s|%s|visible: %d|"
+ "disabled: %d|focused: %d/%d|focus order:%d}\"",
+ obj, obj, elm_widget_type_get(obj),
+ evas_object_name_get(obj), visible, disabled, focused, can_focus,
+ sd->focus_order);
+
+ if (focused)
+ fprintf(output, ", style=bold");
+
+ if (!visible)
+ fprintf(output, ", fontcolor=gray28");
+
+ if ((disabled) || (!visible))
+ fprintf(output, ", color=gray");
+
+ fprintf(output, " ];\n");
+
+ Eina_List *l;
+ Evas_Object *o;
+ EINA_LIST_FOREACH(sd->subobjs, l, o)
+ _sub_obj_tree_dot_dump(o, output);
}
-EOLIAN static const char *
-_elm_widget_item_cursor_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
+#endif
+
+EAPI void
+elm_widget_tree_dump(const Evas_Object *top)
{
- ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
- return elm_object_sub_cursor_get(item->view);
+#ifdef ELM_DEBUG
+ if (!_elm_widget_is(top))
+ return;
+ _sub_obj_tree_dump(top, 0);
+#else
+ (void)top;
+ return;
+#endif
}
-EOLIAN static void
-_elm_widget_item_cursor_unset(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
+EAPI void
+elm_widget_tree_dot_dump(const Evas_Object *top,
+ FILE *output)
{
- ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
- ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
-
- elm_object_cursor_unset(item->view);
+#ifdef ELM_DEBUG
+ if (!_elm_widget_is(top))
+ return;
+ fprintf(output, "graph " " { node [shape=record];\n");
+ _sub_obj_tree_dot_dump(top, output);
+ fprintf(output, "}\n");
+#else
+ (void)top;
+ (void)output;
+ return;
+#endif
}
-/**
- * @internal
- *
- * Sets a different style for this item cursor.
- *
- * @note before you set a style you should define a cursor with
- * elm_widget_item_cursor_set()
- *
- * @param item widget item with cursor already set.
- * @param style the theme style to use (default, transparent, ...)
- *
- * @ingroup Widget
- */
-EOLIAN static void
-_elm_widget_item_cursor_style_set(Eo *eo_item EINA_UNUSED,
- Elm_Widget_Item_Data *item,
- const char *style)
+static void
+_focus_event_changed(void *data EINA_UNUSED, const Efl_Event *event)
{
- ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
- ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
-
- elm_object_sub_cursor_style_set(item->view, style);
+ if (efl_ui_focus_object_focus_get(event->object))
+ evas_object_smart_callback_call(event->object, "focused", NULL);
+ else
+ evas_object_smart_callback_call(event->object, "unfocused", NULL);
}
-/**
- * @internal
- *
- * Get the style for this item cursor.
- *
- * @param item widget item with cursor already set.
- * @return style the theme style in use, defaults to "default". If the
- * object does not have a cursor set, then NULL is returned.
- *
- * @ingroup Widget
- */
-EOLIAN static const char *
-_elm_widget_item_cursor_style_get(const Eo *eo_item EINA_UNUSED,
- Elm_Widget_Item_Data *item)
+EOLIAN static Eo *
+_efl_ui_widget_efl_object_constructor(Eo *obj, Elm_Widget_Smart_Data *sd EINA_UNUSED)
{
- ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
- return elm_object_sub_cursor_style_get(item->view);
-}
+ Eo *parent = NULL;
-/**
- * @internal
- *
- * Set if the cursor set should be searched on the theme or should use
- * the provided by the engine, only.
- *
- * @note before you set if should look on theme you should define a cursor
- * with elm_object_cursor_set(). By default it will only look for cursors
- * provided by the engine.
- *
- * @param item widget item with cursor already set.
- * @param engine_only boolean to define it cursors should be looked only
- * between the provided by the engine or searched on widget's theme as well.
- *
- * @ingroup Widget
- */
-EOLIAN static void
-_elm_widget_item_cursor_engine_only_set(Eo *eo_item EINA_UNUSED,
- Elm_Widget_Item_Data *item,
- Eina_Bool engine_only)
-{
- ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
- ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
+ sd->on_create = EINA_TRUE;
+ efl_canvas_group_clipped_set(obj, EINA_FALSE);
+ obj = efl_constructor(efl_super(obj, MY_CLASS));
+ efl_canvas_object_type_set(obj, MY_CLASS_NAME_LEGACY);
+ evas_object_smart_callbacks_descriptions_set(obj, _smart_callbacks);
+ parent = efl_parent_get(obj);
+ efl_ui_widget_parent_set(obj, parent);
+ sd->on_create = EINA_FALSE;
- elm_object_sub_cursor_theme_search_enabled_set(item->view, !engine_only);
-}
+ efl_access_object_role_set(obj, EFL_ACCESS_ROLE_UNKNOWN);
+ //TIZEN_ONLY(20170717) : expose highlight information on atspi
+ sd->can_highlight = EINA_TRUE;
+ //
+ /***********************************************************
+ * TIZEN_ONLY(20180117): Override Paragraph Direction APIs *
+ ***********************************************************/
+ sd->inherit_paragraph_direction = EINA_TRUE;
-/**
- * @internal
- *
- * Get the cursor engine only usage for this item cursor.
- *
- * @param item widget item with cursor already set.
- * @return engine_only boolean to define it cursors should be looked only
- * between the provided by the engine or searched on widget's theme as well. If
- * the object does not have a cursor set, then EINA_FALSE is returned.
- *
- * @ingroup Widget
- */
-EOLIAN static Eina_Bool
-_elm_widget_item_cursor_engine_only_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
-{
- ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, EINA_FALSE);
- return !elm_object_sub_cursor_theme_search_enabled_get(item->view);
-}
+ if (efl_isa(parent, EFL_CANVAS_OBJECT_CLASS))
+ {
+ if (sd->paragraph_direction != efl_canvas_object_paragraph_direction_get(parent))
+ {
+ sd->paragraph_direction = efl_canvas_object_paragraph_direction_get(parent);
+ _efl_ui_widget_efl_canvas_object_paragraph_direction_set_internal(obj, sd, sd->paragraph_direction);
+ efl_canvas_object_paragraph_direction_set(efl_super(obj, MY_CLASS), sd->paragraph_direction);
+ }
+ }
+ /*******
+ * END *
+ *******/
-EOLIAN static void
-_elm_widget_item_part_content_set(Eo *eo_item EINA_UNUSED,
- Elm_Widget_Item_Data *item,
- const char *part EINA_UNUSED,
- Evas_Object *content EINA_UNUSED)
-{
- ERR_NOT_SUPPORTED(item, "elm_object_part_content_set()");
+ return obj;
}
-EOLIAN static Evas_Object *
-_elm_widget_item_part_content_get(const Eo *eo_item EINA_UNUSED,
- Elm_Widget_Item_Data *item,
- const char *part EINA_UNUSED)
+EOLIAN static Efl_Object*
+_efl_ui_widget_efl_object_finalize(Eo *obj, Elm_Widget_Smart_Data *pd)
{
- ERR_NOT_SUPPORTED(item, "elm_object_part_content_get()");
- return NULL;
-}
+ Eo *eo;
-EOLIAN static Evas_Object *
-_elm_widget_item_part_content_unset(Eo *eo_item EINA_UNUSED,
- Elm_Widget_Item_Data *item,
- const char *part EINA_UNUSED)
-{
- ERR_NOT_SUPPORTED(item, "elm_object_part_content_unset()");
- return NULL;
-}
+ eo = efl_finalize(efl_super(obj, MY_CLASS));
-EOLIAN static void
-_elm_widget_item_part_text_set(Eo *eo_item EINA_UNUSED,
- Elm_Widget_Item_Data *item,
- const char *part EINA_UNUSED,
- const char *label EINA_UNUSED)
-{
- ERR_NOT_SUPPORTED(item, "elm_object_part_text_set()");
-}
+ _full_eval(obj, pd);
-EOLIAN static const char *
-_elm_widget_item_part_text_get(const Eo *eo_item EINA_UNUSED,
- Elm_Widget_Item_Data *item,
- const char *part EINA_UNUSED)
-{
- ERR_NOT_SUPPORTED(item, "elm_object_part_text_get()");
- return NULL;
+ return eo;
}
-static void
-_elm_widget_item_part_text_custom_free(void *data)
-{
- Elm_Label_Data *label;
- label = data;
- eina_stringshare_del(label->part);
- eina_stringshare_del(label->text);
- free(label);
-}
EOLIAN static void
-_elm_widget_item_part_text_custom_set(Eo *eo_item EINA_UNUSED,
- Elm_Widget_Item_Data *item,
- const char *part,
- const char *text)
+_efl_ui_widget_efl_object_destructor(Eo *obj, Elm_Widget_Smart_Data *sd)
{
- Elm_Label_Data *label;
- ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
- ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
+ if (sd->manager.provider)
+ {
+ efl_event_callback_del(sd->manager.provider, EFL_UI_FOCUS_OBJECT_EVENT_MANAGER_CHANGED, _manager_changed_cb, obj);
+ sd->manager.provider = NULL;
+ }
- if (!item->labels)
- item->labels =
- eina_hash_stringshared_new(_elm_widget_item_part_text_custom_free);
- label = eina_hash_find(item->labels, part);
- if (!label)
+ //TIZEN_ONLY : elm_widget_item: add at-spi name setter
+ efl_access_object_description_set(obj, NULL);
+ efl_access_object_i18n_name_set(obj, NULL);
+
+ efl_access_object_description_cb_set(obj, NULL, NULL);
+ efl_access_object_name_cb_set(obj, NULL, NULL);
+ //
+ //TIZEN_ONLY(20170405) Add gesture method to accessible interface
+ efl_access_object_gesture_cb_set(obj, NULL, NULL);
+ //
+ //TIZEN_ONLY : elm_widget_item: add at-spi name setter
+ efl_access_object_translation_domain_set(obj, NULL);
+ efl_access_object_relationships_clear(obj);
+ //
+
+ efl_access_object_attributes_clear(obj);
+ if (sd->logical.parent)
{
- label = malloc(sizeof(Elm_Label_Data));
- if (!label)
- {
- ERR("Failed to allocate memory");
- return;
- }
- label->part = eina_stringshare_add(part);
- label->text = eina_stringshare_add(text);
- eina_hash_add(item->labels, part, label);
+ efl_weak_unref(&sd->logical.parent);
+ sd->logical.parent = NULL;
}
- else
- eina_stringshare_replace(&label->text, text);
-}
-EOLIAN static const char *
-_elm_widget_item_part_text_custom_get(const Eo *eo_item EINA_UNUSED,
- Elm_Widget_Item_Data *item,
- const char *part)
-{
- Elm_Label_Data *label;
- ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
- label = eina_hash_find(item->labels, part);
- return label ? label->text : NULL;
-}
+ // TIZEN_ONLY(20150709) : atspi relations api
+ if (sd->atspi_custom_relations)
+ efl_access_relation_set_free(&sd->atspi_custom_relations);
+ //
-static Eina_Bool
-_elm_widget_item_part_text_custom_foreach(const Eina_Hash *labels EINA_UNUSED,
- const void *key EINA_UNUSED,
- void *data,
- void *func_data)
-{
- Elm_Label_Data *label;
- Elm_Widget_Item_Data *item;
- label = data;
- item = func_data;
+ //TIZEN_ONLY(20150717) add widget name setter
+ if (sd->name)
+ eina_stringshare_del(sd->name);
+ //
- elm_wdg_item_part_text_set(item->eo_obj, label->part, label->text);
+ //TIZEN_ONLY(20150731) : add i18n support for name and description
+ if (sd->atspi_translation_domain)
+ eina_stringshare_del(sd->atspi_translation_domain);
+ ///
- return EINA_TRUE;
+ sd->on_destroy = EINA_TRUE;
+ efl_destructor(efl_super(obj, EFL_UI_WIDGET_CLASS));
+ sd->on_destroy = EINA_FALSE;
}
-EOLIAN static void
-_elm_widget_item_part_text_custom_update(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
-{
- ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
- ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
- if (item->labels)
- eina_hash_foreach(item->labels,
- _elm_widget_item_part_text_custom_foreach, item);
-}
+/* internal eo */
EOLIAN static void
-_elm_widget_item_signal_emit(Eo *eo_item EINA_UNUSED,
- Elm_Widget_Item_Data *item EINA_UNUSED,
- const char *emission EINA_UNUSED,
- const char *source EINA_UNUSED)
+_efl_ui_widget_efl_object_debug_name_override(Eo *obj, Elm_Widget_Smart_Data *sd EINA_UNUSED, Eina_Strbuf *sb)
{
+ const char *focus = "";
+ if (efl_ui_focus_object_focus_get(obj)) focus = ":focused";
+ efl_debug_name_override(efl_super(obj, MY_CLASS), sb);
+ eina_strbuf_append_printf(sb, "%s", focus);
}
-EOLIAN static void
-_elm_widget_item_signal_callback_add(Eo *eo_item,
- Elm_Widget_Item_Data *item,
- const char *emission,
- const char *source,
- Elm_Object_Item_Signal_Cb func,
- void *data)
+EOLIAN static Eina_Bool
+_efl_ui_widget_efl_ui_focus_object_on_focus_update(Eo *obj, Elm_Widget_Smart_Data *sd)
{
- ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
- ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
- EINA_SAFETY_ON_NULL_RETURN(func);
-
- Elm_Widget_Item_Signal_Data *wisd;
+ Eina_Bool focused;
- wisd = malloc(sizeof(Elm_Widget_Item_Signal_Data));
- if (!wisd) return;
-
- wisd->item = eo_item;
- wisd->func = (Elm_Widget_Item_Signal_Cb)func;
- wisd->data = data;
- wisd->emission = eina_stringshare_add(emission);
- wisd->source = eina_stringshare_add(source);
+ if (!elm_widget_can_focus_get(obj))
+ return EINA_FALSE;
- if (_elm_widget_is(item->view))
- elm_object_signal_callback_add(item->view, emission, source, _elm_widget_item_signal_cb, wisd);
- else if (efl_isa(item->view, EFL_CANVAS_LAYOUT_CLASS))
- edje_object_signal_callback_add(item->view, emission, source, _elm_widget_item_signal_cb, wisd);
+ //TIZEN_ONLY(20180607): Restore legacy focus
+ if (elm_widget_is_legacy(obj))
+ focused = elm_widget_focus_get(obj);
else
+ //
+ focused = efl_ui_focus_object_focus_get(obj);
+
+ if (!sd->resize_obj)
+ evas_object_focus_set(obj, focused);
+
+ //TIZEN_ONLY(20180607): Restore legacy focus
+ if (elm_widget_is_legacy(obj))
{
- WRN("The %s widget item doesn't support signal callback add!",
- efl_class_name_get(efl_class_get(item->widget)));
- free(wisd);
- return;
+ if (focused)
+ evas_object_smart_callback_call(obj, "focused", NULL);
+ else
+ evas_object_smart_callback_call(obj, "unfocused", NULL);
}
+ //
- item->signals = eina_list_append(item->signals, wisd);
+ if (_elm_atspi_enabled() && !elm_widget_child_can_focus_get(obj))
+ efl_access_state_changed_signal_emit(obj, EFL_ACCESS_STATE_FOCUSED, focused);
+
+ return EINA_TRUE;
}
-EOLIAN static void *
-_elm_widget_item_signal_callback_del(Eo *eo_item EINA_UNUSED,
- Elm_Widget_Item_Data *item,
- const char *emission,
- const char *source,
- Elm_Object_Item_Signal_Cb func)
+EOLIAN static Eina_Bool
+_efl_ui_widget_on_disabled_update(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED, Eina_Bool disabled EINA_UNUSED)
{
- Elm_Widget_Item_Signal_Data *wisd;
- Eina_List *l;
-
- ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
- ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item, NULL);
- EINA_SAFETY_ON_NULL_RETURN_VAL(func, NULL);
+ return EINA_FALSE;
+}
- EINA_LIST_FOREACH(item->signals, l, wisd)
- {
- if ((wisd->func == (Elm_Widget_Item_Signal_Cb)func) &&
- !strcmp(wisd->emission, emission) &&
- !strcmp(wisd->source, source))
- return _elm_widget_item_signal_callback_list_get(item, l);
- }
+EOLIAN static Eina_Bool
+_efl_ui_widget_widget_event(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED, const Efl_Event *eo_event EINA_UNUSED, Evas_Object *source EINA_UNUSED)
+{
+ return EINA_FALSE;
+}
- return NULL;
+EOLIAN static Eina_Bool
+_efl_ui_widget_on_access_activate(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED, Efl_Ui_Activate act EINA_UNUSED)
+{
+ WRN("The %s widget does not implement the \"activate\" functions.",
+ efl_class_name_get(efl_class_get(obj)));
+ return EINA_TRUE;
}
-//TIZEN_ONLY(20180607): Restore legacy focus
-/**
- * @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)
+EOLIAN static void
+_efl_ui_widget_class_constructor(Efl_Class *klass)
{
- API_ENTRY return;
- Elm_Focus_Move_Policy focus_move_policy = elm_config_focus_move_policy_get();
+ evas_smart_legacy_type_register(MY_CLASS_NAME_LEGACY, klass);
+}
- if (efl_ui_widget_focus_move_policy_automatic_get(obj) &&
- (sd->focus_move_policy != focus_move_policy))
+EOLIAN static Eina_Bool
+_efl_ui_widget_efl_access_component_focus_grab(Eo *obj, Elm_Widget_Smart_Data *pd EINA_UNUSED)
+{
+ if (elm_object_focus_allow_get(obj))
{
- sd->focus_move_policy = focus_move_policy;
+ Ecore_Evas *ee = ecore_evas_ecore_evas_get(evas_object_evas_get(obj));
+ if (!ee) return EINA_FALSE;
+ ecore_evas_activate(ee);
+ elm_object_focus_set(obj, EINA_TRUE);
+ return EINA_TRUE;
}
+ return EINA_FALSE;
}
-EOLIAN static void
-_efl_ui_widget_focus_reconfigure(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
+
+EOLIAN static const char*
+_efl_ui_widget_efl_access_object_i18n_name_get(const Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
{
- const Eina_List *l;
- Evas_Object *child;
- API_ENTRY return;
+ const char *ret, *name;
+ name = efl_access_object_i18n_name_get(efl_super(obj, EFL_UI_WIDGET_CLASS));
- EINA_LIST_FOREACH(sd->subobjs, l, child)
+ if (name) return name;
+
+ //TIZEN_ONLY(20150717) add widget name setter
+ if (_pd->name)
{
- if (elm_widget_is(child))
- efl_ui_widget_focus_reconfigure(child);
+#ifdef HAVE_GETTEXT
+ if (_pd->atspi_translation_domain)
+ return dgettext(_pd->atspi_translation_domain, _pd->name);
+#endif
+ return _pd->name;
}
+ //
- if (sd->hover_obj) efl_ui_widget_focus_reconfigure(sd->hover_obj);
+ //TIZEN_ONLY(20170110) : Ignore text from elm_object_text_set in accessible_name_get
+ Efl_Access_Role role;
+ role = efl_access_object_role_get(obj);
+ if(role == EFL_ACCESS_ROLE_DIALOG || role == EFL_ACCESS_ROLE_PASSWORD_TEXT)
+ return NULL;
+ //
- _elm_widget_focus_move_policy_reload(obj);
-}
-//
-EOLIAN static void
-_elm_widget_item_access_info_set(Eo *eo_item EINA_UNUSED,
- Elm_Widget_Item_Data *item,
- const char *txt)
-{
- ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
- ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
+ ret = elm_object_text_get(obj);
+ if (!ret) return NULL;
- eina_stringshare_del(item->access_info);
- if (!txt) item->access_info = NULL;
- else item->access_info = eina_stringshare_add(txt);
+ return _elm_widget_accessible_plain_name_get(obj, ret);
}
-EOLIAN static void
-_elm_widget_item_translate(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
+EOLIAN static Eina_List*
+_efl_ui_widget_efl_access_object_access_children_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *pd)
{
- ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
- ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
+ Eina_List *l, *accs = NULL;
+ Evas_Object *widget;
+ // TIZEN_ONLY(20160824): Do not append a child, if its accessible parent is different with widget parent
+ Eo *parent;
+ //
+ Eo *proxy = NULL;
-#ifdef HAVE_GETTEXT
- Elm_Translate_String_Data *ts;
- EINA_INLIST_FOREACH(item->translate_strings, ts)
+ EINA_LIST_FOREACH(pd->subobjs, l, widget)
{
- if (!ts->string) continue;
- const char *s = dgettext(ts->domain, ts->string);
- item->on_translate = EINA_TRUE;
- elm_wdg_item_part_text_set(item->eo_obj, ts->id, s);
- item->on_translate = EINA_FALSE;
+ const char *type = evas_object_type_get(widget);
+ // TIZEN ONLY
+ // Ugly Tizen hack to integrate AT-SPI2 accessibility provided by WebKit/Chromium with elementary one.
+ // This wrapper class should be implemented in Webkit/Chromium EFL ports
+ if (type && (!strcmp(type, "EWebView") || !strcmp(type, "WebView")))
+ {
+ elm_atspi_ewk_wrapper_a11y_init(obj, widget);
+ }
}
-#endif
-}
+ EINA_LIST_FOREACH(pd->subobjs, l, widget)
+ {
+ // TIZEN_ONLY(20160705) - enable atspi_proxy to work
+ /* This assumes that only one proxy exists in obj */
+ if (!proxy)
+ {
+ proxy = plug_type_proxy_get(obj, widget);
+ if (proxy)
+ {
+ accs = eina_list_append(accs, proxy);
+ continue;
+ }
+ }
+ //
+ // TIZEN ONLY - END
+ if (!elm_object_widget_check(widget)) continue;
+ if (!efl_isa(widget, EFL_ACCESS_OBJECT_MIXIN)) continue;
+ accs = eina_list_append(accs, widget);
+ }
+ //TIZEN_ONLY(20150709) : spatially sort atspi children
+ // sort children using its top-left coordinate
+ accs = eina_list_sort(accs, -1, _sort_vertically);
+ Eina_List *line, *lines = _lines_split(accs);
+ accs = NULL;
+ EINA_LIST_FREE(lines, line)
+ accs = eina_list_merge(accs, eina_list_sort(line, -1, _sort_horizontally));
+ //
-EOLIAN static void
-_elm_widget_item_access_order_set(Eo *eo_item EINA_UNUSED,
- Elm_Widget_Item_Data *item,
- Eina_List *objs)
-{
- _elm_access_widget_item_access_order_set(item, objs);
-}
+ if (proxy)
+ {
+ Eo *deputy = NULL;
+ accs = eina_list_remove(accs, proxy);
+ EINA_LIST_FOREACH(accs, l, widget)
+ {
+ if (efl_isa(widget, ELM_ACCESS_CLASS))
+ {
+ Elm_Access_Info *info = _elm_access_info_get(widget);
+ if (!info) continue;
+ if (obj == info->part_object)
+ {
+ deputy = widget;
+ break;
+ }
+ }
+ }
-EOLIAN static const Eina_List *
-_elm_widget_item_access_order_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
-{
- return _elm_access_widget_item_access_order_get(item);
-}
+ if (deputy)
+ {
+ accs = eina_list_append_relative(accs, proxy, deputy);
+ }
+ }
-EOLIAN static void
-_elm_widget_item_access_order_unset(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
-{
- _elm_access_widget_item_access_order_unset(item);
+ return accs;
}
-EOLIAN static Evas_Object*
-_elm_widget_item_access_register(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
-{
- _elm_access_widget_item_register(item);
- return item->access_obj;
-}
+/* Legacy APIs */
-EOLIAN static void
-_elm_widget_item_access_unregister(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
+EOLIAN static Efl_Access_State_Set
+_efl_ui_widget_efl_access_object_state_set_get(const Eo *obj, Elm_Widget_Smart_Data *pd EINA_UNUSED)
{
- _elm_access_widget_item_unregister(item);
-}
+ Efl_Access_State_Set states = 0;
-EOLIAN static Evas_Object*
-_elm_widget_item_access_object_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
-{
- return item->access_obj;
-}
+ states = efl_access_object_state_set_get(efl_super(obj, EFL_UI_WIDGET_CLASS));
-EOLIAN static Evas_Object *
-_elm_widget_item_focus_next_object_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item, Elm_Focus_Direction dir)
-{
- Evas_Object *ret = NULL;
+ // TIZEN_ONLY(20171114) Accessibility Highlight Frame added
+ // //TIZEN_ONLY(20171108): bring HIGHLIGHT related changes
+ // Evas_Object *win = elm_widget_top_get(obj);
+ // if (win && efl_isa(win, EFL_UI_WIN_CLASS))
+ // {
+ // if (_elm_win_accessibility_highlight_get(win) == obj)
+ // STATE_TYPE_SET(states, ELM_ATSPI_STATE_HIGHLIGHTED);
+ // }
+ // STATE_TYPE_SET(states, ELM_ATSPI_STATE_HIGHLIGHTABLE);
+ // //
+ //
- if (dir == ELM_FOCUS_PREVIOUS)
- ret = item->focus_previous;
- else if (dir == ELM_FOCUS_NEXT)
- ret = item->focus_next;
- else if (dir == ELM_FOCUS_UP)
- ret = item->focus_up;
- else if (dir == ELM_FOCUS_DOWN)
- ret = item->focus_down;
- else if (dir == ELM_FOCUS_RIGHT)
- ret = item->focus_right;
- else if (dir == ELM_FOCUS_LEFT)
- ret = item->focus_left;
+ if (evas_object_visible_get(obj))
+ {
+ STATE_TYPE_SET(states, EFL_ACCESS_STATE_VISIBLE);
+ if (_elm_widget_onscreen_is(obj))
+ STATE_TYPE_SET(states, EFL_ACCESS_STATE_SHOWING);
+ }
+ if (!elm_widget_child_can_focus_get(obj))
+ {
+ if (elm_object_focus_allow_get(obj))
+ STATE_TYPE_SET(states, EFL_ACCESS_STATE_FOCUSABLE);
+ if (elm_object_focus_get(obj))
+ STATE_TYPE_SET(states, EFL_ACCESS_STATE_FOCUSED);
+ }
+ if (!elm_object_disabled_get(obj))
+ {
+ STATE_TYPE_SET(states, EFL_ACCESS_STATE_ENABLED);
+ STATE_TYPE_SET(states, EFL_ACCESS_STATE_SENSITIVE);
+ }
- return ret;
-}
+ //TIZEN_ONLY(20170717) : expose highlight information on atspi
+ if (_elm_widget_highlightable(obj))
+ STATE_TYPE_SET(states, EFL_ACCESS_STATE_HIGHLIGHTABLE);
+ else
+ STATE_TYPE_UNSET(states, EFL_ACCESS_STATE_HIGHLIGHTABLE);
-EOLIAN static void
-_elm_widget_item_focus_next_object_set(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item, Evas_Object *next, Elm_Focus_Direction dir)
-{
- if (dir == ELM_FOCUS_PREVIOUS)
- item->focus_previous = next;
- else if (dir == ELM_FOCUS_NEXT)
- item->focus_next = next;
- else if (dir == ELM_FOCUS_UP)
- item->focus_up = next;
- else if (dir == ELM_FOCUS_DOWN)
- item->focus_down = next;
- else if (dir == ELM_FOCUS_RIGHT)
- item->focus_right = next;
- else if (dir == ELM_FOCUS_LEFT)
- item->focus_left = next;
+ if (_elm_object_accessibility_currently_highlighted_get() == (void*)pd->obj)
+ STATE_TYPE_SET(states, EFL_ACCESS_STATE_HIGHLIGHTED);
+ //
+
+ return states;
}
-EOLIAN static Elm_Object_Item*
-_elm_widget_item_focus_next_item_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item, Elm_Focus_Direction dir)
+EOLIAN static Eina_List*
+_efl_ui_widget_efl_access_object_attributes_get(const Eo *obj, Elm_Widget_Smart_Data *pd EINA_UNUSED)
{
- Elm_Object_Item *ret = NULL;
+ const char *type = NULL;
+ const char *style = NULL;
+ Eina_List *attr_list = NULL;
+ Efl_Access_Attribute *attr = NULL;
- if (dir == ELM_FOCUS_PREVIOUS)
- ret = item->item_focus_previous;
- else if (dir == ELM_FOCUS_NEXT)
- ret = item->item_focus_next;
- else if (dir == ELM_FOCUS_UP)
- ret = item->item_focus_up;
- else if (dir == ELM_FOCUS_DOWN)
- ret = item->item_focus_down;
- else if (dir == ELM_FOCUS_RIGHT)
- ret = item->item_focus_right;
- else if (dir == ELM_FOCUS_LEFT)
- ret = item->item_focus_left;
+ attr_list = efl_access_object_attributes_get(efl_super(obj, EFL_UI_WIDGET_CLASS));
- return ret;
-}
+ //Add type and style information in addition.
+ type = elm_widget_type_get(obj);
+ if (type)
+ {
+ attr = calloc(1, sizeof(Efl_Access_Attribute));
+ if (attr)
+ {
+ attr->key = eina_stringshare_add("type");
+ attr->value = eina_stringshare_add(type);
+ attr_list = eina_list_append(attr_list, attr);
+ }
+ }
-EOLIAN static void
-_elm_widget_item_focus_next_item_set(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item, Elm_Object_Item *next_item, Elm_Focus_Direction dir)
-{
- if (dir == ELM_FOCUS_PREVIOUS)
- item->item_focus_previous = next_item;
- else if (dir == ELM_FOCUS_NEXT)
- item->item_focus_next = next_item;
- else if (dir == ELM_FOCUS_UP)
- item->item_focus_up = next_item;
- else if (dir == ELM_FOCUS_DOWN)
- item->item_focus_down = next_item;
- else if (dir == ELM_FOCUS_RIGHT)
- item->item_focus_right = next_item;
- else if (dir == ELM_FOCUS_LEFT)
- item->item_focus_left = next_item;
+ style = elm_widget_style_get(obj);
+ if (style)
+ {
+ attr = calloc(1, sizeof(Efl_Access_Attribute));
+ if (attr)
+ {
+ attr->key = eina_stringshare_add("style");
+ attr->value = eina_stringshare_add(style);
+ attr_list = eina_list_append(attr_list, attr);
+ }
+ }
+
+ return attr_list;
}
-/* happy debug functions */
-#ifdef ELM_DEBUG
-static void
-_sub_obj_tree_dump(const Evas_Object *obj,
- int lvl)
+EOLIAN static Eina_List *
+_elm_widget_item_efl_access_object_attributes_get(const Eo *eo_item, Elm_Widget_Item_Data *pd EINA_UNUSED)
{
- int i;
+ const char *style = NULL;
+ Eina_List *attr_list = NULL;
+ Efl_Access_Attribute *attr = NULL;
- for (i = 0; i < lvl * 3; i++)
- putchar(' ');
+ attr_list = efl_access_object_attributes_get(efl_super(eo_item, ELM_WIDGET_ITEM_CLASS));
- if (_elm_widget_is(obj))
+ style = elm_object_item_style_get(eo_item);
+ if (style)
{
- Eina_List *l;
- INTERNAL_ENTRY;
- DBG("+ %s(%p)\n",
- elm_widget_type_get(obj),
- obj);
- EINA_LIST_FOREACH(sd->subobjs, l, obj)
- _sub_obj_tree_dump(obj, lvl + 1);
+ attr = calloc(1, sizeof(Efl_Access_Attribute));
+ if (attr)
+ {
+ attr->key = eina_stringshare_add("style");
+ attr->value = eina_stringshare_add(style);
+ attr_list = eina_list_append(attr_list, attr);
+ }
}
- else
- DBG("+ %s(%p)\n", evas_object_type_get(obj), obj);
+ return attr_list;
}
-static void
-_sub_obj_tree_dot_dump(const Evas_Object *obj,
- FILE *output)
+EOLIAN static Eina_Rect
+_elm_widget_item_efl_access_component_extents_get(const Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *sd EINA_UNUSED, Eina_Bool screen_coords)
{
- if (!_elm_widget_is(obj))
- return;
- INTERNAL_ENTRY;
+ Eina_Rect r = EINA_RECT(-1, -1, -1, -1);
+ int ee_x, ee_y;
- Eina_Bool visible = evas_object_visible_get(obj);
- Eina_Bool disabled = elm_widget_disabled_get(obj);
- Eina_Bool focused = efl_ui_focus_object_focus_get(obj);
- Eina_Bool can_focus = elm_widget_can_focus_get(obj);
+ if (!sd->view) return r;
- if (sd->parent_obj)
+ r = efl_gfx_entity_geometry_get(sd->view);
+ if (screen_coords)
{
- fprintf(output, "\"%p\" -- \"%p\" [ color=black", sd->parent_obj, obj);
+ Ecore_Evas *ee = ecore_evas_ecore_evas_get(evas_object_evas_get(sd->view));
+ if (ee)
+ {
+ ecore_evas_geometry_get(ee, &ee_x, &ee_y, NULL, NULL);
+ r.x += ee_x;
+ r.y += ee_y;
+ }
+ }
+ return r;
+}
- if (focused)
- fprintf(output, ", style=bold");
+EOLIAN static Eina_Bool
+_elm_widget_item_efl_access_component_extents_set(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *sd EINA_UNUSED, Eina_Bool screen_coords EINA_UNUSED, Eina_Rect r EINA_UNUSED)
+{
+ return EINA_FALSE;
+}
- if (!visible)
- fprintf(output, ", color=gray28");
+EOLIAN static Eina_Bool
+_elm_widget_item_efl_access_component_focus_grab(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *_pd EINA_UNUSED)
+{
+ elm_object_item_focus_set(obj, EINA_TRUE);
+ return elm_object_item_focus_get(obj);
+}
- fprintf(output, " ];\n");
- }
+EOLIAN static Efl_Object *
+_efl_ui_widget_efl_object_provider_find(const Eo *obj, Elm_Widget_Smart_Data *pd, const Efl_Object *klass)
+{
+ Efl_Object *lookup = NULL;
- fprintf(output, "\"%p\" [ label = \"{%p|%s|%s|visible: %d|"
- "disabled: %d|focused: %d/%d|focus order:%d}\"",
- obj, obj, elm_widget_type_get(obj),
- evas_object_name_get(obj), visible, disabled, focused, can_focus,
- sd->focus_order);
+ if ((klass == EFL_CONFIG_INTERFACE) || (klass == EFL_CONFIG_GLOBAL_CLASS))
+ return _efl_config_obj;
- if (focused)
- fprintf(output, ", style=bold");
+ if (klass == EFL_ACCESS_OBJECT_MIXIN)
+ return (Eo*)obj;
- if (!visible)
- fprintf(output, ", fontcolor=gray28");
+ if (pd->provider_lookup) return NULL;
+ pd->provider_lookup = EINA_TRUE;
- if ((disabled) || (!visible))
- fprintf(output, ", color=gray");
+ if (pd->parent_obj) lookup = efl_provider_find(pd->parent_obj, klass);
+ if (!lookup) lookup = efl_provider_find(efl_super(obj, MY_CLASS), klass);
- fprintf(output, " ];\n");
+ pd->provider_lookup = EINA_FALSE;
- Eina_List *l;
- Evas_Object *o;
- EINA_LIST_FOREACH(sd->subobjs, l, o)
- _sub_obj_tree_dot_dump(o, output);
+ return lookup;
}
-#endif
-
-EAPI void
-elm_widget_tree_dump(const Evas_Object *top)
+EOLIAN static Efl_Ui_Focus_Manager*
+_efl_ui_widget_efl_ui_focus_object_focus_parent_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *pd EINA_UNUSED)
{
-#ifdef ELM_DEBUG
- if (!_elm_widget_is(top))
- return;
- _sub_obj_tree_dump(top, 0);
-#else
- (void)top;
- return;
-#endif
+ return pd->focus.parent;
}
-EAPI void
-elm_widget_tree_dot_dump(const Evas_Object *top,
- FILE *output)
+EOLIAN static Efl_Ui_Focus_Manager*
+_efl_ui_widget_efl_ui_focus_object_focus_manager_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *pd EINA_UNUSED)
{
-#ifdef ELM_DEBUG
- if (!_elm_widget_is(top))
- return;
- fprintf(output, "graph " " { node [shape=record];\n");
- _sub_obj_tree_dot_dump(top, output);
- fprintf(output, "}\n");
-#else
- (void)top;
- (void)output;
- return;
-#endif
+ return pd->focus.manager;
}
-static void
-_focus_event_changed(void *data EINA_UNUSED, const Efl_Event *event)
+EOLIAN static Eina_Rect
+_efl_ui_widget_efl_ui_focus_object_focus_geometry_get(const Eo *obj, Elm_Widget_Smart_Data *pd EINA_UNUSED)
{
- if (efl_ui_focus_object_focus_get(event->object))
- evas_object_smart_callback_call(event->object, "focused", NULL);
- else
- evas_object_smart_callback_call(event->object, "unfocused", NULL);
+ return efl_gfx_entity_geometry_get(obj);
}
-EOLIAN static Eo *
-_efl_ui_widget_efl_object_constructor(Eo *obj, Elm_Widget_Smart_Data *sd EINA_UNUSED)
+EOLIAN static void
+_efl_ui_widget_efl_ui_focus_object_focus_set(Eo *obj, Elm_Widget_Smart_Data *pd, Eina_Bool focus)
{
- Eo *parent = NULL;
-
- sd->on_create = EINA_TRUE;
- efl_canvas_group_clipped_set(obj, EINA_FALSE);
- obj = efl_constructor(efl_super(obj, MY_CLASS));
- efl_canvas_object_type_set(obj, MY_CLASS_NAME_LEGACY);
- evas_object_smart_callbacks_descriptions_set(obj, _smart_callbacks);
- parent = efl_parent_get(obj);
- efl_ui_widget_parent_set(obj, parent);
- sd->on_create = EINA_FALSE;
-
- efl_access_object_role_set(obj, EFL_ACCESS_ROLE_UNKNOWN);
- //TIZEN_ONLY(20170717) : expose highlight information on atspi
- sd->can_highlight = EINA_TRUE;
- //
- /***********************************************************
- * TIZEN_ONLY(20180117): Override Paragraph Direction APIs *
- ***********************************************************/
- sd->inherit_paragraph_direction = EINA_TRUE;
+ pd->focused = focus;
- if (efl_isa(parent, EFL_CANVAS_OBJECT_CLASS))
- {
- if (sd->paragraph_direction != efl_canvas_object_paragraph_direction_get(parent))
- {
- sd->paragraph_direction = efl_canvas_object_paragraph_direction_get(parent);
- _efl_ui_widget_efl_canvas_object_paragraph_direction_set_internal(obj, sd, sd->paragraph_direction);
- efl_canvas_object_paragraph_direction_set(efl_super(obj, MY_CLASS), sd->paragraph_direction);
- }
- }
- /*******
- * END *
- *******/
+ efl_ui_focus_object_focus_set(efl_super(obj, MY_CLASS), focus);
- return obj;
+ efl_ui_focus_object_on_focus_update(obj);
}
-EOLIAN static Efl_Object*
-_efl_ui_widget_efl_object_finalize(Eo *obj, Elm_Widget_Smart_Data *pd)
+EOLIAN static Efl_Ui_Focus_Manager*
+_efl_ui_widget_focus_manager_create(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *pd EINA_UNUSED, Efl_Ui_Focus_Object *root EINA_UNUSED)
{
- Eo *eo;
+ ERR("No manager presented");
+ return NULL;
+}
- eo = efl_finalize(efl_super(obj, MY_CLASS));
+//TIZEN_ONLY(20160726): add API elm_object_part_access_object_get
+EOLIAN static Evas_Object*
+_efl_ui_widget_part_access_object_get(const Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED, const char *part EINA_UNUSED)
+{
+ WRN("The %s widget does not implement the \"part_access_object_get\" functions.",
+ efl_class_name_get(efl_class_get(obj)));
+ return NULL;
+}
+//
- _full_eval(obj, pd);
+/* Legacy APIs */
- return eo;
+/* elm_object_content_xxx APIs are supposed to work on all objects for which
+ * elm_object_widget_check() returns true. The below checks avoid printing out
+ * undesired ERR messages. */
+EAPI void
+elm_widget_content_part_set(Evas_Object *obj, const char *part, Evas_Object *content)
+{
+ ELM_WIDGET_CHECK(obj);
+ if (efl_isa(obj, EFL_UI_LAYOUT_CLASS))
+ {
+ elm_layout_content_set(obj, part, content);
+ return;
+ }
+ if (!efl_isa(obj, EFL_PART_INTERFACE)) return;
+ if (!part)
+ {
+ part = efl_ui_widget_default_content_part_get(obj);
+ if (!part) return;
+ }
+ efl_content_set(efl_part(obj, part), content);
}
+EAPI Evas_Object *
+elm_widget_content_part_get(const Evas_Object *obj, const char *part)
+{
+ ELM_WIDGET_CHECK(obj) NULL;
+ if (efl_isa(obj, EFL_UI_LAYOUT_CLASS))
+ return elm_layout_content_get(obj, part);
+ if (!efl_isa(obj, EFL_PART_INTERFACE)) return NULL;
+ if (!part)
+ {
+ part = efl_ui_widget_default_content_part_get(obj);
+ if (!part) return NULL;
+ }
+ return efl_content_get(efl_part(obj, part));
+}
-EOLIAN static void
-_efl_ui_widget_efl_object_destructor(Eo *obj, Elm_Widget_Smart_Data *sd)
+EAPI Evas_Object *
+elm_widget_content_part_unset(Evas_Object *obj, const char *part)
{
- if (sd->manager.provider)
+ ELM_WIDGET_CHECK(obj) NULL;
+ if (efl_isa(obj, EFL_UI_LAYOUT_CLASS))
+ return elm_layout_content_unset(obj, part);
+ if (!efl_isa(obj, EFL_PART_INTERFACE)) return NULL;
+ if (!part)
{
- efl_event_callback_del(sd->manager.provider, EFL_UI_FOCUS_OBJECT_EVENT_MANAGER_CHANGED, _manager_changed_cb, obj);
- sd->manager.provider = NULL;
+ part = efl_ui_widget_default_content_part_get(obj);
+ if (!part) return NULL;
}
+ return efl_content_unset(efl_part(obj, part));
+}
- //TIZEN_ONLY : elm_widget_item: add at-spi name setter
- efl_access_object_description_set(obj, NULL);
- efl_access_object_i18n_name_set(obj, NULL);
+EAPI void
+elm_widget_signal_emit(Eo *obj, const char *emission, const char *source)
+{
+ ELM_WIDGET_CHECK(obj);
- efl_access_object_description_cb_set(obj, NULL, NULL);
- efl_access_object_name_cb_set(obj, NULL, NULL);
- //
- //TIZEN_ONLY(20170405) Add gesture method to accessible interface
- efl_access_object_gesture_cb_set(obj, NULL, NULL);
- //
- //TIZEN_ONLY : elm_widget_item: add at-spi name setter
- efl_access_object_translation_domain_set(obj, NULL);
- efl_access_object_relationships_clear(obj);
- //
+ if (efl_isa(obj, EFL_UI_LAYOUT_CLASS))
+ elm_layout_signal_emit(obj, emission, source);
+ else if (evas_object_smart_type_check(obj, "elm_icon"))
+ {
+ WRN("Deprecated function. This functionality on icon objects"
+ " will be dropped on a next release.");
+ _elm_icon_signal_emit(obj, emission, source);
+ }
+}
- efl_access_object_attributes_clear(obj);
- if (sd->logical.parent)
+EAPI void
+elm_widget_signal_callback_add(Eo *obj, const char *emission, const char *source, Edje_Signal_Cb func, void *data)
+{
+ ELM_WIDGET_CHECK(obj);
+ EINA_SAFETY_ON_NULL_RETURN(func);
+ if (evas_object_smart_type_check(obj, "elm_layout"))
+ elm_layout_signal_callback_add(obj, emission, source, func, data);
+ else if (evas_object_smart_type_check(obj, "elm_icon"))
{
- efl_weak_unref(&sd->logical.parent);
- sd->logical.parent = NULL;
+ WRN("Deprecated function. This functionality on icon objects"
+ " will be dropped on a next release.");
+
+ _elm_icon_signal_callback_add(obj, emission, source, func, data);
}
+}
- // TIZEN_ONLY(20150709) : atspi relations api
- if (sd->atspi_custom_relations)
- efl_access_relation_set_free(&sd->atspi_custom_relations);
- //
+EAPI void *
+elm_widget_signal_callback_del(Eo *obj, const char *emission, const char *source, Edje_Signal_Cb func)
+{
+ void *data = NULL;
- //TIZEN_ONLY(20150717) add widget name setter
- if (sd->name)
- eina_stringshare_del(sd->name);
- //
+ ELM_WIDGET_CHECK(obj) NULL;
+ EINA_SAFETY_ON_NULL_RETURN_VAL(func, NULL);
+ if (evas_object_smart_type_check(obj, "elm_layout"))
+ data = elm_layout_signal_callback_del(obj, emission, source, func);
+ else if (evas_object_smart_type_check(obj, "elm_icon"))
+ {
+ WRN("Deprecated function. This functionality on icon objects"
+ " will be dropped on a next release.");
- //TIZEN_ONLY(20150731) : add i18n support for name and description
- if (sd->atspi_translation_domain)
- eina_stringshare_del(sd->atspi_translation_domain);
- ///
+ data = _elm_icon_signal_callback_del(obj, emission, source, func);
+ }
- sd->on_destroy = EINA_TRUE;
- efl_destructor(efl_super(obj, EFL_UI_WIDGET_CLASS));
- sd->on_destroy = EINA_FALSE;
+ return data;
}
-/* internal eo */
-EOLIAN static void
-_efl_ui_widget_efl_object_debug_name_override(Eo *obj, Elm_Widget_Smart_Data *sd EINA_UNUSED, Eina_Strbuf *sb)
+/* Widget Shadow Begin */
+
+typedef struct _Widget_Shadow
{
- const char *focus = "";
+ Eo *widget;
+ Eo *surface;
+ struct {
+ double rx, ry, ox, oy, grow;
+ int r, g, b, a;
+ } props;
+ Eina_Stringshare *code, *name;
+} Widget_Shadow;
- if (efl_ui_focus_object_focus_get(obj)) focus = ":focused";
- efl_debug_name_override(efl_super(obj, MY_CLASS), sb);
- eina_strbuf_append_printf(sb, "%s", focus);
-}
+static void _widget_shadow_update(Widget_Shadow *shadow);
-EOLIAN static Eina_Bool
-_efl_ui_widget_efl_ui_focus_object_on_focus_update(Eo *obj, Elm_Widget_Smart_Data *sd)
+static void
+_widget_shadow_del_cb(void *data, const Efl_Event *ev EINA_UNUSED)
{
- Eina_Bool focused;
+ Widget_Shadow *shadow = data;
- if (!elm_widget_can_focus_get(obj))
- return EINA_FALSE;
+ efl_del(shadow->surface);
+ free(shadow);
+}
- //TIZEN_ONLY(20180607): Restore legacy focus
- if (elm_widget_is_legacy(obj))
- focused = elm_widget_focus_get(obj);
- else
- //
- focused = efl_ui_focus_object_focus_get(obj);
+static void
+_widget_shadow_event_cb(void *data, const Efl_Event *ev EINA_UNUSED)
+{
+ Widget_Shadow *shadow = data;
+ _widget_shadow_update(shadow);
+}
- if (!sd->resize_obj)
- evas_object_focus_set(obj, focused);
+EFL_CALLBACKS_ARRAY_DEFINE(widget_shadow_cb,
+{ EFL_EVENT_DEL, _widget_shadow_del_cb },
+{ EFL_GFX_ENTITY_EVENT_POSITION_CHANGED, _widget_shadow_event_cb },
+{ EFL_GFX_ENTITY_EVENT_SIZE_CHANGED, _widget_shadow_event_cb },
+{ EFL_GFX_ENTITY_EVENT_STACK_CHANGED, _widget_shadow_event_cb },
+{ EFL_GFX_ENTITY_EVENT_HIDE, _widget_shadow_event_cb },
+{ EFL_GFX_ENTITY_EVENT_SHOW, _widget_shadow_event_cb })
- //TIZEN_ONLY(20180607): Restore legacy focus
- if (elm_widget_is_legacy(obj))
+static Widget_Shadow *
+_widget_shadow_part_get(const Eo *part_obj)
+{
+ Elm_Part_Data *pd = efl_data_scope_get(part_obj, EFL_UI_WIDGET_PART_CLASS);
+ Widget_Shadow *shadow;
+ Eo *widget = pd->obj;
+
+ shadow = efl_key_data_get(widget, "__elm_shadow");
+ if (!shadow)
{
- if (focused)
- evas_object_smart_callback_call(obj, "focused", NULL);
- else
- evas_object_smart_callback_call(obj, "unfocused", NULL);
+ shadow = calloc(1, sizeof(*shadow));
+ if (!shadow) return NULL;
+ shadow->widget = pd->obj;
+ efl_key_data_set(widget, "__elm_shadow", shadow);
+ efl_event_callback_array_add(widget, widget_shadow_cb(), shadow);
}
- //
+ return shadow;
+}
- if (_elm_atspi_enabled() && !elm_widget_child_can_focus_get(obj))
- efl_access_state_changed_signal_emit(obj, EFL_ACCESS_STATE_FOCUSED, focused);
+static void
+_widget_shadow_update(Widget_Shadow *ws)
+{
+ int l = 0, r = 0, t = 0, b = 0;
+ Eina_Rect srect, wrect;
+ char filter[1024];
- return EINA_TRUE;
+#define FILTER_FMT \
+ "a = buffer { 'alpha' }" \
+ "grow { %f, dst = a, alphaonly = true }" \
+ "blur { src = a, rx = %f, ry = %f, color = color(%d,%d,%d,%d) }"
+
+ if (!ws->surface)
+ {
+ ws->surface = efl_add(EFL_CANVAS_PROXY_CLASS, ws->widget);
+ efl_gfx_fill_auto_set(ws->surface, 1);
+ efl_canvas_proxy_source_clip_set(ws->surface, EINA_FALSE);
+ efl_canvas_proxy_source_events_set(ws->surface, EINA_FALSE);
+ efl_canvas_proxy_source_set(ws->surface, ws->widget);
+ }
+
+ if (!ws->code)
+ {
+ snprintf(filter, sizeof(filter), FILTER_FMT,
+ ws->props.grow, ws->props.rx, ws->props.ry,
+ ws->props.r, ws->props.g, ws->props.b, ws->props.a);
+ }
+
+ efl_gfx_filter_program_set(ws->surface,
+ ws->code ? ws->code : filter,
+ ws->name ? ws->name : "shadow");
+ efl_gfx_filter_padding_get(ws->surface, &l, &r, &t, &b);
+
+ wrect = efl_gfx_entity_geometry_get(ws->widget);
+ srect.x = wrect.x + (int) (-l + ws->props.ox);
+ srect.y = wrect.y + (int) (-t + ws->props.oy);
+ srect.w = wrect.w + (int) (l + r);
+ srect.h = wrect.h + (int) (t + b);
+
+ if ((!ws->props.a && !ws->code) ||
+ !efl_gfx_entity_visible_get(ws->widget))
+ {
+ efl_gfx_entity_visible_set(ws->surface, EINA_FALSE);
+ return;
+ }
+
+ efl_canvas_object_clip_set(ws->surface, efl_canvas_object_clip_get(ws->widget));
+ efl_canvas_group_member_add(efl_canvas_object_render_parent_get(ws->widget), ws->surface);
+ efl_gfx_entity_geometry_set(ws->surface, srect);
+ efl_gfx_stack_below(ws->surface, ws->widget);
+ efl_gfx_entity_visible_set(ws->surface, EINA_TRUE);
}
-EOLIAN static Eina_Bool
-_efl_ui_widget_on_disabled_update(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED, Eina_Bool disabled EINA_UNUSED)
+static void
+_elm_widget_shadow_update(Efl_Ui_Widget *obj)
{
- return EINA_FALSE;
+ Widget_Shadow *shadow = _widget_shadow_part_get(obj);
+ _widget_shadow_update(shadow);
}
-EOLIAN static Eina_Bool
-_efl_ui_widget_widget_event(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED, const Efl_Event *eo_event EINA_UNUSED, Evas_Object *source EINA_UNUSED)
+EOLIAN static void
+_efl_ui_widget_part_shadow_efl_gfx_blur_offset_set(Eo *obj, void *_pd EINA_UNUSED, double ox, double oy)
{
- return EINA_FALSE;
+ Widget_Shadow *shadow = _widget_shadow_part_get(obj);
+ shadow->props.ox = ox;
+ shadow->props.oy = oy;
+ _widget_shadow_update(shadow);
}
-EOLIAN static Eina_Bool
-_efl_ui_widget_on_access_activate(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED, Efl_Ui_Activate act EINA_UNUSED)
+EOLIAN static void
+_efl_ui_widget_part_shadow_efl_gfx_blur_offset_get(const Eo *obj, void *_pd EINA_UNUSED, double *ox, double *oy)
{
- WRN("The %s widget does not implement the \"activate\" functions.",
- efl_class_name_get(efl_class_get(obj)));
- return EINA_TRUE;
+ Widget_Shadow *shadow = _widget_shadow_part_get(obj);
+ if (ox) *ox = shadow->props.ox;
+ if (oy) *oy = shadow->props.oy;
}
EOLIAN static void
-_efl_ui_widget_class_constructor(Efl_Class *klass)
+_efl_ui_widget_part_shadow_efl_gfx_blur_radius_set(Eo *obj, void *_pd EINA_UNUSED, double rx, double ry)
{
- evas_smart_legacy_type_register(MY_CLASS_NAME_LEGACY, klass);
+ Widget_Shadow *shadow = _widget_shadow_part_get(obj);
+ shadow->props.rx = rx;
+ shadow->props.ry = ry;
+ _widget_shadow_update(shadow);
}
-EOLIAN static Eina_Bool
-_efl_ui_widget_efl_access_component_focus_grab(Eo *obj, Elm_Widget_Smart_Data *pd EINA_UNUSED)
+EOLIAN static void
+_efl_ui_widget_part_shadow_efl_gfx_blur_radius_get(const Eo *obj, void *_pd EINA_UNUSED, double *rx, double *ry)
{
- if (elm_object_focus_allow_get(obj))
- {
- Ecore_Evas *ee = ecore_evas_ecore_evas_get(evas_object_evas_get(obj));
- if (!ee) return EINA_FALSE;
- ecore_evas_activate(ee);
- elm_object_focus_set(obj, EINA_TRUE);
- return EINA_TRUE;
- }
- return EINA_FALSE;
+ Widget_Shadow *shadow = _widget_shadow_part_get(obj);
+ if (rx) *rx = shadow->props.rx;
+ if (ry) *ry = shadow->props.ry;
}
-//TIZEN_ONLY(20150717) add widget name setter
-EOLIAN void
-_efl_ui_widget_efl_access_object_i18n_name_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data* _pd EINA_UNUSED, const char *name)
+EOLIAN static void
+_efl_ui_widget_part_shadow_efl_gfx_color_color_set(Eo *obj, void *_pd EINA_UNUSED, int r, int g, int b, int a)
{
- if (_pd->name)
- eina_stringshare_del(_pd->name);
-
- _pd->name = eina_stringshare_add(name);
+ Widget_Shadow *shadow = _widget_shadow_part_get(obj);
+ shadow->props.r = r;
+ shadow->props.g = g;
+ shadow->props.b = b;
+ shadow->props.a = a;
+ _widget_shadow_update(shadow);
}
-//
-EOLIAN static const char*
-_efl_ui_widget_efl_access_object_i18n_name_get(const Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
+EOLIAN static void
+_efl_ui_widget_part_shadow_efl_gfx_color_color_get(const Eo *obj, void *_pd EINA_UNUSED, int *r, int *g, int *b, int *a)
{
- const char *ret, *name;
- name = efl_access_object_i18n_name_get(efl_super(obj, EFL_UI_WIDGET_CLASS));
-
- if (name) return name;
-
- //TIZEN_ONLY(20150717) add widget name setter
- if (_pd->name)
- {
-#ifdef HAVE_GETTEXT
- if (_pd->atspi_translation_domain)
- return dgettext(_pd->atspi_translation_domain, _pd->name);
-#endif
- return _pd->name;
- }
- //
-
- //TIZEN_ONLY(20170110) : Ignore text from elm_object_text_set in accessible_name_get
- Efl_Access_Role role;
- role = efl_access_object_role_get(obj);
- if(role == EFL_ACCESS_ROLE_DIALOG || role == EFL_ACCESS_ROLE_PASSWORD_TEXT)
- return NULL;
- //
-
- ret = elm_object_text_get(obj);
- if (!ret) return NULL;
-
- return _elm_widget_accessible_plain_name_get(obj, ret);
+ Widget_Shadow *shadow = _widget_shadow_part_get(obj);
+ if (r) *r = shadow->props.r;
+ if (g) *g = shadow->props.g;
+ if (b) *b = shadow->props.b;
+ if (a) *a = shadow->props.a;
}
-//TIZEN_ONLY(20161111) add widget/widget_item description get/set
-EOLIAN void
-_efl_ui_widget_efl_access_object_description_set(Eo *obj EINA_UNUSED, Efl_Ui_Widget_Data* _pd, const char *description)
+EOLIAN static void
+_efl_ui_widget_part_shadow_efl_gfx_blur_grow_set(Eo *obj, void *_pd EINA_UNUSED, double radius)
{
- if (_pd->description)
- eina_stringshare_del(_pd->description);
-
- _pd->description = eina_stringshare_add(description);
+ Widget_Shadow *shadow = _widget_shadow_part_get(obj);
+ shadow->props.grow = radius;
+ _widget_shadow_update(shadow);
}
-EOLIAN static const char*
-_efl_ui_widget_efl_access_object_description_get(const Eo *obj EINA_UNUSED, Efl_Ui_Widget_Data *_pd EINA_UNUSED)
+EOLIAN static double
+_efl_ui_widget_part_shadow_efl_gfx_blur_grow_get(const Eo *obj, void *_pd EINA_UNUSED)
{
- const char *ret = NULL;
- ret = efl_access_object_description_get(efl_super(obj, EFL_UI_WIDGET_CLASS));
- if (ret) return ret;
-
-#ifdef HAVE_GETTEXT
- if (_pd->atspi_translation_domain)
- return dgettext(_pd->atspi_translation_domain, _pd->description);
-#endif
- return _pd->description;
+ Widget_Shadow *shadow = _widget_shadow_part_get(obj);
+ return shadow->props.grow;
}
-//
-//TIZEN_ONLY(20171108): make atspi_proxy work
-static void
-_proxy_widget_move_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
+EOLIAN static void
+_efl_ui_widget_part_shadow_efl_gfx_filter_filter_program_set(Eo *obj, void *_pd EINA_UNUSED, const char *code, const char *name)
{
- Evas_Coord x, y;
- Eo *proxy = data;
-
- evas_object_geometry_get(obj, &x, &y, NULL, NULL);
- elm_atspi_bridge_utils_proxy_offset_set(proxy, x, y);
+ Widget_Shadow *ws = _widget_shadow_part_get(obj);
+ eina_stringshare_replace(&ws->code, code);
+ eina_stringshare_replace(&ws->name, name);
+ _widget_shadow_update(ws);
}
-static void
-_on_widget_del(void *data, const Efl_Event *event)
+EOLIAN static void
+_efl_ui_widget_part_shadow_efl_gfx_filter_filter_program_get(const Eo *obj, void *_pd EINA_UNUSED, const char **code, const char **name)
{
- Eo *plug = data;
- evas_object_event_callback_del_full(event->object, EVAS_CALLBACK_MOVE,
- _proxy_widget_move_cb, plug);
- efl_del(plug);
+ Widget_Shadow *ws = _widget_shadow_part_get(obj);
+ efl_gfx_filter_program_get(ws->surface, code, name);
}
-static void
-_on_proxy_connected_cb(void *data, const Efl_Event *event)
+EOLIAN static void
+_efl_ui_widget_part_shadow_efl_gfx_filter_filter_source_set(Eo *obj, void *_pd EINA_UNUSED, const char *name, Efl_Gfx_Entity *source)
{
- Evas_Coord x, y;
- Evas_Object *widget = data;
-
- evas_object_geometry_get(widget, &x, &y, NULL, NULL);
- elm_atspi_bridge_utils_proxy_offset_set(event->object, x, y);
-
- evas_object_event_callback_add(widget, EVAS_CALLBACK_MOVE, _proxy_widget_move_cb, event->object);
+ Widget_Shadow *ws = _widget_shadow_part_get(obj);
+ _widget_shadow_update(ws);
+ efl_gfx_filter_source_set(ws->surface, name, source);
}
-//
-//TIZEN_ONLY(20161111) add widget/widget_item description get/set
-EOLIAN void
-_elm_widget_item_efl_access_object_description_set(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data* _pd EINA_UNUSED, const char *description)
+EOLIAN static Efl_Gfx_Entity *
+_efl_ui_widget_part_shadow_efl_gfx_filter_filter_source_get(const Eo *obj, void *_pd EINA_UNUSED, const char *name)
{
- if (_pd->description)
- eina_stringshare_del(_pd->description);
-
- _pd->description = eina_stringshare_add(description);
+ Widget_Shadow *ws = _widget_shadow_part_get(obj);
+ return efl_gfx_filter_source_get(ws->surface, name);
}
-EOLIAN const char*
-_elm_widget_item_efl_access_object_description_get(const Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *_pd EINA_UNUSED)
+EOLIAN static void
+_efl_ui_widget_part_shadow_efl_gfx_filter_filter_data_set(Eo *obj, void *_pd EINA_UNUSED, const char *name, const char *value, Eina_Bool execute)
{
- const char *ret = NULL;
- ret = efl_access_object_description_get(efl_super(obj, ELM_WIDGET_ITEM_CLASS));
- if (ret) return ret;
-
-#ifdef HAVE_GETTEXT
- if (_pd->atspi_translation_domain)
- return dgettext(_pd->atspi_translation_domain, _pd->description);
-#endif
- return _pd->description;
+ Widget_Shadow *ws = _widget_shadow_part_get(obj);
+ _widget_shadow_update(ws);
+ efl_gfx_filter_data_set(ws->surface, name, value, execute);
}
-//
-//TIZEN_ONLY(20150713) : add atspi name setter to widget_item
-EOLIAN void
-_elm_widget_item_efl_access_object_i18n_name_set(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data* _pd EINA_UNUSED, const char *name)
+EOLIAN static void
+_efl_ui_widget_part_shadow_efl_gfx_filter_filter_data_get(const Eo *obj, void *_pd EINA_UNUSED, const char *name, const char **value, Eina_Bool *execute)
{
- if (_pd->name)
- eina_stringshare_del(_pd->name);
-
- _pd->name = eina_stringshare_add(name);
+ Widget_Shadow *ws = _widget_shadow_part_get(obj);
+ efl_gfx_filter_data_get(ws->surface, name, value, execute);
}
-EOLIAN const char*
-_elm_widget_item_efl_access_object_i18n_name_get(const Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *_pd EINA_UNUSED)
+EOLIAN static void
+_efl_ui_widget_part_shadow_efl_gfx_filter_filter_padding_get(const Eo *obj, void *_pd EINA_UNUSED, int *l, int *r, int *t, int *b)
{
- //TIZEN_ONLY(20190922): add name callback, description callback.
- const char *ret = NULL;
- ret = efl_access_object_i18n_name_get(efl_super(obj, ELM_WIDGET_ITEM_CLASS));
- if (ret) return ret;
- //
-
- if (_pd->name)
- {
-#ifdef HAVE_GETTEXT
- if (_pd->atspi_translation_domain)
- return dgettext(_pd->atspi_translation_domain, _pd->name);
-#endif
- return _pd->name;
- }
-
- return NULL;
+ Widget_Shadow *ws = _widget_shadow_part_get(obj);
+ efl_gfx_filter_padding_get(ws->surface, l, r, t, b);
}
-///
-//TIZEN_ONLY(20150731) : add i18n support for name and description
EOLIAN static void
-_efl_ui_widget_efl_access_object_translation_domain_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd, const char *domain)
+_efl_ui_widget_part_shadow_efl_gfx_filter_filter_state_set(Eo *obj, void *_pd EINA_UNUSED, const char *cur_state, double cur_val, const char *next_state, double next_val, double pos)
{
- eina_stringshare_replace(&_pd->atspi_translation_domain, domain);
+ Widget_Shadow *ws = _widget_shadow_part_get(obj);
+ efl_gfx_filter_state_set(ws->surface, cur_state, cur_val, next_state, next_val, pos);
}
-EOLIAN static const char*
-_efl_ui_widget_efl_access_object_translation_domain_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd)
+EOLIAN static void
+_efl_ui_widget_part_shadow_efl_gfx_filter_filter_state_get(const Eo *obj, void *_pd EINA_UNUSED, const char **cur_state, double *cur_val, const char **next_state, double *next_val, double *pos)
{
- return _pd->atspi_translation_domain;
+ Widget_Shadow *ws = _widget_shadow_part_get(obj);
+ efl_gfx_filter_state_get(ws->surface, cur_state, cur_val, next_state, next_val, pos);
}
-EOLIAN static void
-_elm_widget_item_efl_access_object_translation_domain_set(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *_pd, const char *domain)
+#include "efl_ui_widget_part_shadow.eo.c"
+
+/* Widget Shadow End */
+
+
+/* Efl.Part implementation */
+
+EOLIAN static Efl_Object *
+_efl_ui_widget_efl_part_part_get(const Eo *obj, Elm_Widget_Smart_Data *wd EINA_UNUSED, const char *part)
{
- eina_stringshare_replace(&_pd->atspi_translation_domain, domain);
+ if (eina_streq(part, "background"))
+ return ELM_PART_IMPLEMENT(EFL_UI_WIDGET_PART_BG_CLASS, obj, part);
+ else if (eina_streq(part, "shadow"))
+ return ELM_PART_IMPLEMENT(EFL_UI_WIDGET_PART_SHADOW_CLASS, obj, part);
+ return ELM_PART_IMPLEMENT(EFL_UI_WIDGET_PART_CLASS, obj, part);
}
-EOLIAN static const char*
-_elm_widget_item_efl_access_object_translation_domain_get(const Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *_pd)
+EOLIAN static void \
+_efl_ui_widget_part_efl_object_destructor(Eo *obj, Elm_Part_Data *pd)
{
- return _pd->atspi_translation_domain;
+ ELM_PART_HOOK;
+ eina_tmpstr_del(pd->part);
+ efl_destructor(efl_super(obj, EFL_UI_WIDGET_PART_CLASS));
}
-///
-static int _sort_vertically(const void *data1, const void *data2)
-{
- Evas_Coord y1, y2;
- evas_object_geometry_get(data1, NULL, &y1, NULL, NULL);
- evas_object_geometry_get(data2, NULL, &y2, NULL, NULL);
+#include "efl_ui_widget_part.eo.c"
- return y1 < y2 ? -1 : 1;
-}
+/* Efl.Part end */
-static int _sort_horizontally(const void *data1, const void *data2)
+/* Efl.Part Bg implementation */
+
+Efl_Canvas_Object *
+_efl_ui_widget_bg_get(const Efl_Ui_Widget *obj)
{
- Evas_Coord x1, x2;
- evas_object_geometry_get(data1, &x1, NULL, NULL, NULL);
- evas_object_geometry_get(data2, &x2, NULL, NULL, NULL);
+ Elm_Widget_Smart_Data *sd = efl_data_scope_get(obj, MY_CLASS);
+ Evas_Object *bg_obj = sd->bg;
- return x1 < x2 ? -1 : 1;
+ if (!bg_obj)
+ {
+ bg_obj = efl_add(EFL_UI_BG_CLASS, obj);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(bg_obj, NULL);
+ sd->bg = bg_obj;
+ efl_canvas_group_member_add(obj, sd->bg);
+ evas_object_stack_below(sd->bg, sd->resize_obj);
+ _smart_reconfigure(sd);
+ }
+
+ return bg_obj;
}
-static Eina_List *_lines_split(Eina_List *children)
+static inline Efl_Canvas_Object *
+efl_ui_widget_part_bg_get(const Eo *part_obj)
{
- Eo *c;
- Eina_List *lines, *line, *l;
- Evas_Coord yl, y, hl, h;
- lines = line = NULL;
-
- if (!children) return NULL;
+ Elm_Part_Data *pd = efl_data_scope_get(part_obj, EFL_UI_WIDGET_PART_CLASS);
+ return _efl_ui_widget_bg_get(pd->obj);
+}
- EINA_LIST_FOREACH(children, l, c)
- {
- evas_object_geometry_get(c, NULL, &yl, NULL, &hl);
+EOLIAN static Eina_Bool
+_efl_ui_widget_part_bg_efl_file_file_set(Eo *obj, void *pd EINA_UNUSED, const char *file, const char *key)
+{
+ Evas_Object *bg_obj = efl_ui_widget_part_bg_get(obj);
- /* remove child if its height == 0 */
- if (hl != 0) break;
- }
+ return efl_file_set(bg_obj, file, key);
+}
- EINA_LIST_FREE(children, c)
- {
- evas_object_geometry_get(c, NULL, &y, NULL, &h);
+EOLIAN static void
+_efl_ui_widget_part_bg_efl_file_file_get(const Eo *obj, void *pd EINA_UNUSED, const char **file, const char **key)
+{
+ Evas_Object *bg_obj = efl_ui_widget_part_bg_get(obj);
- /* remove child if its height == 0 */
- if (h == 0) continue;
+ efl_file_get(bg_obj, file, key);
+}
- if ((yl + (int)(0.25 * hl)) >= y)
- {
- //same line
- line = eina_list_append(line,c);
- }
- else
- {
- // finish current line & start new
- lines = eina_list_append(lines, line);
- yl = y, hl = h;
- line = eina_list_append(NULL, c);
- }
- }
+EOLIAN static void
+_efl_ui_widget_part_bg_efl_gfx_color_color_set(Eo *obj, void *pd EINA_UNUSED, int r, int g, int b, int a)
+{
+ Evas_Object *bg_obj = efl_ui_widget_part_bg_get(obj);
- return eina_list_append(lines, line);
+ efl_gfx_color_set(bg_obj, r, g, b, a);
}
-//
-//TIZEN_ONLY(20171114) atspi: integrate ewk_view with elementary accessibility
-static void
-_on_ewk_del(void *data, const Efl_Event *desc EINA_UNUSED)
+EOLIAN static void
+_efl_ui_widget_part_bg_efl_gfx_color_color_get(const Eo *obj, void *pd EINA_UNUSED, int *r, int *g, int *b, int *a)
{
- Eo *plug = data;
- efl_del(plug);
+ Evas_Object *bg_obj = efl_ui_widget_part_bg_get(obj);
+
+ efl_gfx_color_get(bg_obj, r, g, b, a);
}
-//
-//TIZEN_ONLY(20170621) handle atspi proxy connection at runtime
-Eo *
-plug_type_proxy_get(Eo *obj, Evas_Object *widget)
+EOLIAN static void
+_efl_ui_widget_part_bg_efl_gfx_image_scale_type_set(Eo *obj, void *pd EINA_UNUSED, Efl_Gfx_Image_Scale_Type scale_type)
{
- Eo *proxy = NULL;
- const char *plug_id;
- char *svcname, *svcnum;
+ Evas_Object *bg_obj = efl_ui_widget_part_bg_get(obj);
- if ((plug_id = evas_object_data_get(widget, "___PLUGID")) != NULL)
- {
- // TIZEN_ONLY(20160930) : endless recursion fix
- efl_access_object_attribute_append(efl_super(obj, MY_CLASS), "___PlugID", plug_id);
- efl_access_object_role_set(obj, EFL_ACCESS_ROLE_EMBEDDED);
+ efl_gfx_image_scale_type_set(bg_obj, scale_type);
+}
- proxy = evas_object_data_get(widget, "__widget_proxy");
- // TIZEN_ONLY(20171109) : fix for invalid proxy object, when at-spi has been restarted
- if (proxy)
- {
- if (!evas_object_data_get(proxy, "__proxy_invalid")) return proxy;
- evas_object_data_del(widget, "__widget_proxy");
- }
- //
+EOLIAN static Efl_Gfx_Image_Scale_Type
+_efl_ui_widget_part_bg_efl_gfx_image_scale_type_get(const Eo *obj, void *pd EINA_UNUSED)
- if (_elm_atspi_bridge_plug_id_split(plug_id, &svcname, &svcnum))
- {
- proxy = _elm_atspi_bridge_utils_proxy_create(obj, svcname, atoi(svcnum), ELM_ATSPI_PROXY_TYPE_PLUG);
- evas_object_data_set(widget, "__widget_proxy", proxy);
- efl_event_callback_add(widget, EFL_EVENT_DEL, _on_widget_del, proxy);
- efl_event_callback_add(proxy, ELM_ATSPI_PROXY_EVENT_CONNECTED, _on_proxy_connected_cb, widget);
- elm_atspi_bridge_utils_proxy_connect(proxy);
- free(svcname);
- free(svcnum);
- }
- }
+{
+ Evas_Object *bg_obj = efl_ui_widget_part_bg_get(obj);
- return proxy;
+ return efl_gfx_image_scale_type_get(bg_obj);
}
-EAPI Eo *
-elm_widget_atspi_plug_type_proxy_get(Evas_Object *obj)
-{
- Elm_Widget_Smart_Data *wd;
- Evas_Object *widget;
- Eina_List *l;
+#include "efl_ui_widget_part_bg.eo.c"
- wd = efl_data_scope_get(obj, EFL_UI_WIDGET_CLASS);
- if (!wd) return NULL;
+/* Efl.Part Bg end */
- Eo *proxy = NULL;
- EINA_LIST_FOREACH(wd->subobjs, l, widget)
- {
- proxy = plug_type_proxy_get(obj, widget);
- if (proxy) break;
- }
- return proxy;
-}
-//
-
-
-EOLIAN static Eina_List*
-_efl_ui_widget_efl_access_object_access_children_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *pd)
-{
- Eina_List *l, *accs = NULL;
- Evas_Object *widget;
- // TIZEN_ONLY(20160824): Do not append a child, if its accessible parent is different with widget parent
- Eo *parent;
- //
- Eo *proxy = NULL;
-
- EINA_LIST_FOREACH(pd->subobjs, l, widget)
- {
- const char *type = evas_object_type_get(widget);
- // TIZEN ONLY
- // Ugly Tizen hack to integrate AT-SPI2 accessibility provided by WebKit/Chromium with elementary one.
- // This wrapper class should be implemented in Webkit/Chromium EFL ports
- if (type && (!strcmp(type, "EWebView") || !strcmp(type, "WebView")))
- {
- elm_atspi_ewk_wrapper_a11y_init(obj, widget);
- }
- }
- EINA_LIST_FOREACH(pd->subobjs, l, widget)
- {
- // TIZEN_ONLY(20160705) - enable atspi_proxy to work
- /* This assumes that only one proxy exists in obj */
- if (!proxy)
- {
- proxy = plug_type_proxy_get(obj, widget);
- if (proxy)
- {
- accs = eina_list_append(accs, proxy);
- continue;
- }
- }
- //
- // TIZEN ONLY - END
- if (!elm_object_widget_check(widget)) continue;
- if (!efl_isa(widget, EFL_ACCESS_OBJECT_MIXIN)) continue;
- accs = eina_list_append(accs, widget);
- }
- //TIZEN_ONLY(20150709) : spatially sort atspi children
- // sort children using its top-left coordinate
- accs = eina_list_sort(accs, -1, _sort_vertically);
- Eina_List *line, *lines = _lines_split(accs);
- accs = NULL;
- EINA_LIST_FREE(lines, line)
- accs = eina_list_merge(accs, eina_list_sort(line, -1, _sort_horizontally));
- //
-
- if (proxy)
- {
- Eo *deputy = NULL;
- accs = eina_list_remove(accs, proxy);
- EINA_LIST_FOREACH(accs, l, widget)
- {
- if (efl_isa(widget, ELM_ACCESS_CLASS))
- {
- Elm_Access_Info *info = _elm_access_info_get(widget);
- if (!info) continue;
- if (obj == info->part_object)
- {
- deputy = widget;
- break;
- }
- }
- }
-
- if (deputy)
- {
- accs = eina_list_append_relative(accs, proxy, deputy);
- }
- }
-
- return accs;
-}
-
-//TIZEN_ONLY(20161107): enhance elm_atspi_accessible_can_highlight_set to set can_hihglight property to its children
-EAPI Eina_Bool
-_elm_widget_highlightable(Evas_Object *obj)
-{
- Eo *parent;
-
- Elm_Widget_Smart_Data *wd = efl_data_scope_get(obj, EFL_UI_WIDGET_CLASS);
- if (!wd) return EINA_FALSE;
- if (!wd->can_highlight) return EINA_FALSE;
-
- parent = efl_provider_find(efl_parent_get(obj), EFL_ACCESS_OBJECT_MIXIN);
- while (parent && !efl_isa(parent, ELM_ATSPI_APP_OBJECT_CLASS))
- {
- //TIZEN_ONLY(20160929) : atspi: Improves how to find the can_highlight of the widget
- if (!_elm_widget_can_highlight_get_by_class(parent)) return EINA_FALSE;
- //
- parent = efl_provider_find(efl_parent_get(parent), EFL_ACCESS_OBJECT_MIXIN);
- }
- return EINA_TRUE;
-}
-//
-
-/* Legacy APIs */
-
-EOLIAN static Efl_Access_State_Set
-_efl_ui_widget_efl_access_object_state_set_get(const Eo *obj, Elm_Widget_Smart_Data *pd EINA_UNUSED)
-{
- Efl_Access_State_Set states = 0;
-
- states = efl_access_object_state_set_get(efl_super(obj, EFL_UI_WIDGET_CLASS));
-
- // TIZEN_ONLY(20171114) Accessibility Highlight Frame added
- // //TIZEN_ONLY(20171108): bring HIGHLIGHT related changes
- // Evas_Object *win = elm_widget_top_get(obj);
- // if (win && efl_isa(win, EFL_UI_WIN_CLASS))
- // {
- // if (_elm_win_accessibility_highlight_get(win) == obj)
- // STATE_TYPE_SET(states, ELM_ATSPI_STATE_HIGHLIGHTED);
- // }
- // STATE_TYPE_SET(states, ELM_ATSPI_STATE_HIGHLIGHTABLE);
- // //
- //
-
- if (evas_object_visible_get(obj))
- {
- STATE_TYPE_SET(states, EFL_ACCESS_STATE_VISIBLE);
- if (_elm_widget_onscreen_is(obj))
- STATE_TYPE_SET(states, EFL_ACCESS_STATE_SHOWING);
- }
- if (!elm_widget_child_can_focus_get(obj))
- {
- if (elm_object_focus_allow_get(obj))
- STATE_TYPE_SET(states, EFL_ACCESS_STATE_FOCUSABLE);
- if (elm_object_focus_get(obj))
- STATE_TYPE_SET(states, EFL_ACCESS_STATE_FOCUSED);
- }
- if (!elm_object_disabled_get(obj))
- {
- STATE_TYPE_SET(states, EFL_ACCESS_STATE_ENABLED);
- STATE_TYPE_SET(states, EFL_ACCESS_STATE_SENSITIVE);
- }
- //TIZEN_ONLY(20170717) : expose highlight information on atspi
- if (_elm_widget_highlightable(obj))
- STATE_TYPE_SET(states, EFL_ACCESS_STATE_HIGHLIGHTABLE);
- else
- STATE_TYPE_UNSET(states, EFL_ACCESS_STATE_HIGHLIGHTABLE);
+/* Internal EO APIs and hidden overrides */
- if (_elm_object_accessibility_currently_highlighted_get() == (void*)pd->obj)
- STATE_TYPE_SET(states, EFL_ACCESS_STATE_HIGHLIGHTED);
- //
+EFL_FUNC_BODY_CONST(efl_ui_widget_default_content_part_get, const char *, NULL)
+EFL_FUNC_BODY_CONST(efl_ui_widget_default_text_part_get, const char *, NULL)
- return states;
-}
+ELM_PART_CONTENT_DEFAULT_GET(efl_ui_widget, NULL)
+ELM_PART_TEXT_DEFAULT_GET(efl_ui_widget, NULL)
-EOLIAN static Eina_List*
-_efl_ui_widget_efl_access_object_attributes_get(const Eo *obj, Elm_Widget_Smart_Data *pd EINA_UNUSED)
-{
- const char *type = NULL;
- const char *style = NULL;
- Eina_List *attr_list = NULL;
- Efl_Access_Attribute *attr = NULL;
+/***********************************************************************************
+ * TIZEN_ONLY_FEATURE: apply Tizen's color_class features. *
+ ***********************************************************************************/
+/* Internal EO APIs and hidden overrides */
+EAPI EFL_FUNC_BODYV(elm_widget_class_color_set, Eina_Bool, EINA_FALSE,
+ EFL_FUNC_CALL(color_class, r, g, b, a),
+ const char *color_class, int r, int g, int b, int a)
+EAPI EFL_FUNC_BODYV(elm_widget_class_color_get, Eina_Bool, EINA_FALSE,
+ EFL_FUNC_CALL(color_class, r, g, b, a),
+ const char *color_class, int *r, int *g, int *b, int *a)
+EAPI EFL_FUNC_BODYV(elm_widget_class_color2_set, Eina_Bool, EINA_FALSE,
+ EFL_FUNC_CALL(color_class, r, g, b, a),
+ const char *color_class, int r, int g, int b, int a)
+EAPI EFL_FUNC_BODYV(elm_widget_class_color2_get, Eina_Bool, EINA_FALSE,
+ EFL_FUNC_CALL(color_class, r, g, b, a),
+ const char *color_class, int *r, int *g, int *b, int *a)
+EAPI EFL_FUNC_BODYV(elm_widget_class_color3_set, Eina_Bool, EINA_FALSE,
+ EFL_FUNC_CALL(color_class, r, g, b, a),
+ const char *color_class, int r, int g, int b, int a)
+EAPI EFL_FUNC_BODYV(elm_widget_class_color3_get, Eina_Bool, EINA_FALSE,
+ EFL_FUNC_CALL(color_class, r, g, b, a),
+ const char *color_class, int *r, int *g, int *b, int *a)
+EAPI EFL_VOID_FUNC_BODYV(elm_widget_class_color_del,
+ EFL_FUNC_CALL(color_class),
+ const char *color_class)
+EAPI EFL_VOID_FUNC_BODY(elm_widget_class_color_clear)
- attr_list = efl_access_object_attributes_get(efl_super(obj, EFL_UI_WIDGET_CLASS));
+static Eina_Bool _elm_widget_class_color_set(Eo *obj, Elm_Widget_Smart_Data *sd EINA_UNUSED, const char *color_class, int r, int g, int b, int a);
+static Eina_Bool _elm_widget_class_color_get(Eo *obj, Elm_Widget_Smart_Data *sd EINA_UNUSED, const char *color_class, int *r, int *g, int *b, int *a);
+static Eina_Bool _elm_widget_class_color2_set(Eo *obj, Elm_Widget_Smart_Data *sd EINA_UNUSED, const char *color_class, int r, int g, int b, int a);
+static Eina_Bool _elm_widget_class_color2_get(Eo *obj, Elm_Widget_Smart_Data *sd EINA_UNUSED, const char *color_class, int *r, int *g, int *b, int *a);
+static Eina_Bool _elm_widget_class_color3_set(Eo *obj, Elm_Widget_Smart_Data *sd EINA_UNUSED, const char *color_class, int r, int g, int b, int a);
+static Eina_Bool _elm_widget_class_color3_get(Eo *obj, Elm_Widget_Smart_Data *sd EINA_UNUSED, const char *color_class, int *r, int *g, int *b, int *a);
+static void _elm_widget_class_color_del(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, const char *color_class);
+static void _elm_widget_class_color_clear(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd);
+/*******
+ * END *
+ *******/
- //Add type and style information in addition.
- type = elm_widget_type_get(obj);
- if (type)
- {
- attr = calloc(1, sizeof(Efl_Access_Attribute));
- if (attr)
- {
- attr->key = eina_stringshare_add("type");
- attr->value = eina_stringshare_add(type);
- attr_list = eina_list_append(attr_list, attr);
- }
- }
- style = elm_widget_style_get(obj);
- if (style)
- {
- attr = calloc(1, sizeof(Efl_Access_Attribute));
- if (attr)
- {
- attr->key = eina_stringshare_add("style");
- attr->value = eina_stringshare_add(style);
- attr_list = eina_list_append(attr_list, attr);
- }
- }
+#define EFL_UI_WIDGET_EXTRA_OPS \
+ EFL_CANVAS_GROUP_ADD_DEL_OPS(efl_ui_widget), \
+ ELM_PART_CONTENT_DEFAULT_OPS(efl_ui_widget), \
+ ELM_PART_TEXT_DEFAULT_OPS(efl_ui_widget), \
+ EFL_OBJECT_OP_FUNC(efl_dbg_info_get, _efl_ui_widget_efl_object_dbg_info_get), \
+/*********************************************************************************** \
+ * TIZEN_ONLY_FEATURE: apply Tizen's color_class features. * \
+ ***********************************************************************************/ \
+ EFL_OBJECT_OP_FUNC(elm_widget_class_color_set, _elm_widget_class_color_set), \
+ EFL_OBJECT_OP_FUNC(elm_widget_class_color_get, _elm_widget_class_color_get), \
+ EFL_OBJECT_OP_FUNC(elm_widget_class_color2_set, _elm_widget_class_color2_set), \
+ EFL_OBJECT_OP_FUNC(elm_widget_class_color2_get, _elm_widget_class_color2_get), \
+ EFL_OBJECT_OP_FUNC(elm_widget_class_color3_set, _elm_widget_class_color3_set), \
+ EFL_OBJECT_OP_FUNC(elm_widget_class_color3_get, _elm_widget_class_color3_get), \
+ EFL_OBJECT_OP_FUNC(elm_widget_class_color_del, _elm_widget_class_color_del), \
+ EFL_OBJECT_OP_FUNC(elm_widget_class_color_clear, _elm_widget_class_color_clear)
- return attr_list;
-}
+/*******
+ * END *
+ *******/
// TIZEN_ONLY(20150709) : atspi relations api
EOLIAN static Efl_Access_Relation_Set
}
//////////////////////////////
-EOLIAN static Eina_List *
-_elm_widget_item_efl_access_object_attributes_get(const Eo *eo_item, Elm_Widget_Item_Data *pd EINA_UNUSED)
-{
- const char *style = NULL;
- Eina_List *attr_list = NULL;
- Efl_Access_Attribute *attr = NULL;
-
- attr_list = efl_access_object_attributes_get(efl_super(eo_item, ELM_WIDGET_ITEM_CLASS));
-
- style = elm_object_item_style_get(eo_item);
- if (style)
- {
- attr = calloc(1, sizeof(Efl_Access_Attribute));
- if (attr)
- {
- attr->key = eina_stringshare_add("style");
- attr->value = eina_stringshare_add(style);
- attr_list = eina_list_append(attr_list, attr);
- }
- }
- return attr_list;
-}
-
-EOLIAN static Eina_Rect
-_elm_widget_item_efl_access_component_extents_get(const Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *sd EINA_UNUSED, Eina_Bool screen_coords)
-{
- Eina_Rect r = EINA_RECT(-1, -1, -1, -1);
- int ee_x, ee_y;
-
- if (!sd->view) return r;
-
- r = efl_gfx_entity_geometry_get(sd->view);
- if (screen_coords)
- {
- Ecore_Evas *ee = ecore_evas_ecore_evas_get(evas_object_evas_get(sd->view));
- if (ee)
- {
- ecore_evas_geometry_get(ee, &ee_x, &ee_y, NULL, NULL);
- r.x += ee_x;
- r.y += ee_y;
- }
- }
- return r;
-}
-
-EOLIAN static Eina_Bool
-_elm_widget_item_efl_access_component_extents_set(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *sd EINA_UNUSED, Eina_Bool screen_coords EINA_UNUSED, Eina_Rect r EINA_UNUSED)
-{
- return EINA_FALSE;
-}
-
-EOLIAN static Eina_Bool
-_elm_widget_item_efl_access_component_focus_grab(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *_pd EINA_UNUSED)
-{
- elm_object_item_focus_set(obj, EINA_TRUE);
- return elm_object_item_focus_get(obj);
-}
-
//TIZEN_ONLY(20160726): add API elm_atspi_accessible_can_highlight_set/get
static Eina_Bool
_children_highlight_check(Eo *obj)
}
//
-EOLIAN static Efl_Object *
-_efl_ui_widget_efl_object_provider_find(const Eo *obj, Elm_Widget_Smart_Data *pd, const Efl_Object *klass)
+// TIZEN_ONLY(20150705): Genlist item align feature
+EAPI void
+elm_widget_scroll_item_align_enabled_set(Evas_Object *obj,
+ Eina_Bool scroll_item_align_enable)
{
- Efl_Object *lookup = NULL;
+ API_ENTRY return;
+ if (sd->scroll_item_align_enable == scroll_item_align_enable) return;
+ sd->scroll_item_align_enable = scroll_item_align_enable;
+}
- if ((klass == EFL_CONFIG_INTERFACE) || (klass == EFL_CONFIG_GLOBAL_CLASS))
- return _efl_config_obj;
+EAPI Eina_Bool
+elm_widget_scroll_item_align_enabled_get(const Evas_Object *obj)
+{
+ API_ENTRY return EINA_FALSE;
+ return sd->scroll_item_align_enable;
+}
- if (klass == EFL_ACCESS_OBJECT_MIXIN)
- return (Eo*)obj;
- if (pd->provider_lookup) return NULL;
- pd->provider_lookup = EINA_TRUE;
+//TIZEN_ONLY(20150717) add widget name setter
+EOLIAN void
+_efl_ui_widget_efl_access_object_i18n_name_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data* _pd EINA_UNUSED, const char *name)
+{
+ if (_pd->name)
+ eina_stringshare_del(_pd->name);
- if (pd->parent_obj) lookup = efl_provider_find(pd->parent_obj, klass);
- if (!lookup) lookup = efl_provider_find(efl_super(obj, MY_CLASS), klass);
+ _pd->name = eina_stringshare_add(name);
+}
+//
- pd->provider_lookup = EINA_FALSE;
+//TIZEN_ONLY(20161111) add widget/widget_item description get/set
+EOLIAN void
+_efl_ui_widget_efl_access_object_description_set(Eo *obj EINA_UNUSED, Efl_Ui_Widget_Data* _pd, const char *description)
+{
+ if (_pd->description)
+ eina_stringshare_del(_pd->description);
- return lookup;
+ _pd->description = eina_stringshare_add(description);
}
-EOLIAN static Efl_Ui_Focus_Manager*
-_efl_ui_widget_efl_ui_focus_object_focus_parent_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *pd EINA_UNUSED)
+EOLIAN static const char*
+_efl_ui_widget_efl_access_object_description_get(const Eo *obj EINA_UNUSED, Efl_Ui_Widget_Data *_pd EINA_UNUSED)
{
- return pd->focus.parent;
+ const char *ret = NULL;
+ ret = efl_access_object_description_get(efl_super(obj, EFL_UI_WIDGET_CLASS));
+ if (ret) return ret;
+
+#ifdef HAVE_GETTEXT
+ if (_pd->atspi_translation_domain)
+ return dgettext(_pd->atspi_translation_domain, _pd->description);
+#endif
+ return _pd->description;
}
+//
-EOLIAN static Efl_Ui_Focus_Manager*
-_efl_ui_widget_efl_ui_focus_object_focus_manager_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *pd EINA_UNUSED)
+//TIZEN_ONLY(20171108): make atspi_proxy work
+static void
+_proxy_widget_move_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
{
- return pd->focus.manager;
+ Evas_Coord x, y;
+ Eo *proxy = data;
+
+ evas_object_geometry_get(obj, &x, &y, NULL, NULL);
+ elm_atspi_bridge_utils_proxy_offset_set(proxy, x, y);
}
-EOLIAN static Eina_Rect
-_efl_ui_widget_efl_ui_focus_object_focus_geometry_get(const Eo *obj, Elm_Widget_Smart_Data *pd EINA_UNUSED)
+static void
+_on_widget_del(void *data, const Efl_Event *event)
{
- return efl_gfx_entity_geometry_get(obj);
+ Eo *plug = data;
+ evas_object_event_callback_del_full(event->object, EVAS_CALLBACK_MOVE,
+ _proxy_widget_move_cb, plug);
+ efl_del(plug);
}
-EOLIAN static void
-_efl_ui_widget_efl_ui_focus_object_focus_set(Eo *obj, Elm_Widget_Smart_Data *pd, Eina_Bool focus)
+static void
+_on_proxy_connected_cb(void *data, const Efl_Event *event)
{
- pd->focused = focus;
+ Evas_Coord x, y;
+ Evas_Object *widget = data;
- efl_ui_focus_object_focus_set(efl_super(obj, MY_CLASS), focus);
+ evas_object_geometry_get(widget, &x, &y, NULL, NULL);
+ elm_atspi_bridge_utils_proxy_offset_set(event->object, x, y);
- efl_ui_focus_object_on_focus_update(obj);
+ evas_object_event_callback_add(widget, EVAS_CALLBACK_MOVE, _proxy_widget_move_cb, event->object);
}
+//
-EOLIAN static Efl_Ui_Focus_Manager*
-_efl_ui_widget_focus_manager_create(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *pd EINA_UNUSED, Efl_Ui_Focus_Object *root EINA_UNUSED)
+//TIZEN_ONLY(20161111) add widget/widget_item description get/set
+EOLIAN void
+_elm_widget_item_efl_access_object_description_set(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data* _pd EINA_UNUSED, const char *description)
{
- ERR("No manager presented");
- return NULL;
+ if (_pd->description)
+ eina_stringshare_del(_pd->description);
+
+ _pd->description = eina_stringshare_add(description);
}
-//TIZEN_ONLY(20160726): add API elm_object_part_access_object_get
-EOLIAN static Evas_Object*
-_efl_ui_widget_part_access_object_get(const Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED, const char *part EINA_UNUSED)
+EOLIAN const char*
+_elm_widget_item_efl_access_object_description_get(const Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *_pd EINA_UNUSED)
{
- WRN("The %s widget does not implement the \"part_access_object_get\" functions.",
- efl_class_name_get(efl_class_get(obj)));
- return NULL;
+ const char *ret = NULL;
+ ret = efl_access_object_description_get(efl_super(obj, ELM_WIDGET_ITEM_CLASS));
+ if (ret) return ret;
+
+#ifdef HAVE_GETTEXT
+ if (_pd->atspi_translation_domain)
+ return dgettext(_pd->atspi_translation_domain, _pd->description);
+#endif
+ return _pd->description;
}
//
-/* Legacy APIs */
+//TIZEN_ONLY(20150713) : add atspi name setter to widget_item
+EOLIAN void
+_elm_widget_item_efl_access_object_i18n_name_set(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data* _pd EINA_UNUSED, const char *name)
+{
+ if (_pd->name)
+ eina_stringshare_del(_pd->name);
-/* elm_object_content_xxx APIs are supposed to work on all objects for which
- * elm_object_widget_check() returns true. The below checks avoid printing out
- * undesired ERR messages. */
-EAPI void
-elm_widget_content_part_set(Evas_Object *obj, const char *part, Evas_Object *content)
+ _pd->name = eina_stringshare_add(name);
+}
+
+EOLIAN const char*
+_elm_widget_item_efl_access_object_i18n_name_get(const Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *_pd EINA_UNUSED)
{
- ELM_WIDGET_CHECK(obj);
- if (efl_isa(obj, EFL_UI_LAYOUT_CLASS))
- {
- elm_layout_content_set(obj, part, content);
- return;
- }
- if (!efl_isa(obj, EFL_PART_INTERFACE)) return;
- if (!part)
+ //TIZEN_ONLY(20190922): add name callback, description callback.
+ const char *ret = NULL;
+ ret = efl_access_object_i18n_name_get(efl_super(obj, ELM_WIDGET_ITEM_CLASS));
+ if (ret) return ret;
+ //
+
+ if (_pd->name)
{
- part = efl_ui_widget_default_content_part_get(obj);
- if (!part) return;
+#ifdef HAVE_GETTEXT
+ if (_pd->atspi_translation_domain)
+ return dgettext(_pd->atspi_translation_domain, _pd->name);
+#endif
+ return _pd->name;
}
- efl_content_set(efl_part(obj, part), content);
+
+ return NULL;
}
+///
-EAPI Evas_Object *
-elm_widget_content_part_get(const Evas_Object *obj, const char *part)
+//TIZEN_ONLY(20150731) : add i18n support for name and description
+EOLIAN static void
+_efl_ui_widget_efl_access_object_translation_domain_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd, const char *domain)
{
- ELM_WIDGET_CHECK(obj) NULL;
- if (efl_isa(obj, EFL_UI_LAYOUT_CLASS))
- return elm_layout_content_get(obj, part);
- if (!efl_isa(obj, EFL_PART_INTERFACE)) return NULL;
- if (!part)
- {
- part = efl_ui_widget_default_content_part_get(obj);
- if (!part) return NULL;
- }
- return efl_content_get(efl_part(obj, part));
+ eina_stringshare_replace(&_pd->atspi_translation_domain, domain);
}
-EAPI Evas_Object *
-elm_widget_content_part_unset(Evas_Object *obj, const char *part)
+EOLIAN static const char*
+_efl_ui_widget_efl_access_object_translation_domain_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd)
{
- ELM_WIDGET_CHECK(obj) NULL;
- if (efl_isa(obj, EFL_UI_LAYOUT_CLASS))
- return elm_layout_content_unset(obj, part);
- if (!efl_isa(obj, EFL_PART_INTERFACE)) return NULL;
- if (!part)
- {
- part = efl_ui_widget_default_content_part_get(obj);
- if (!part) return NULL;
- }
- return efl_content_unset(efl_part(obj, part));
+ return _pd->atspi_translation_domain;
}
-EAPI void
-elm_widget_signal_emit(Eo *obj, const char *emission, const char *source)
+EOLIAN static void
+_elm_widget_item_efl_access_object_translation_domain_set(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *_pd, const char *domain)
{
- ELM_WIDGET_CHECK(obj);
+ eina_stringshare_replace(&_pd->atspi_translation_domain, domain);
+}
- if (efl_isa(obj, EFL_UI_LAYOUT_CLASS))
- elm_layout_signal_emit(obj, emission, source);
- else if (evas_object_smart_type_check(obj, "elm_icon"))
- {
- WRN("Deprecated function. This functionality on icon objects"
- " will be dropped on a next release.");
- _elm_icon_signal_emit(obj, emission, source);
- }
+EOLIAN static const char*
+_elm_widget_item_efl_access_object_translation_domain_get(const Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *_pd)
+{
+ return _pd->atspi_translation_domain;
}
+///
-EAPI void
-elm_widget_signal_callback_add(Eo *obj, const char *emission, const char *source, Edje_Signal_Cb func, void *data)
+static int _sort_vertically(const void *data1, const void *data2)
{
- ELM_WIDGET_CHECK(obj);
- EINA_SAFETY_ON_NULL_RETURN(func);
- if (evas_object_smart_type_check(obj, "elm_layout"))
- elm_layout_signal_callback_add(obj, emission, source, func, data);
- else if (evas_object_smart_type_check(obj, "elm_icon"))
- {
- WRN("Deprecated function. This functionality on icon objects"
- " will be dropped on a next release.");
+ Evas_Coord y1, y2;
+ evas_object_geometry_get(data1, NULL, &y1, NULL, NULL);
+ evas_object_geometry_get(data2, NULL, &y2, NULL, NULL);
- _elm_icon_signal_callback_add(obj, emission, source, func, data);
- }
+ return y1 < y2 ? -1 : 1;
}
-EAPI void *
-elm_widget_signal_callback_del(Eo *obj, const char *emission, const char *source, Edje_Signal_Cb func)
+static int _sort_horizontally(const void *data1, const void *data2)
{
- void *data = NULL;
+ Evas_Coord x1, x2;
+ evas_object_geometry_get(data1, &x1, NULL, NULL, NULL);
+ evas_object_geometry_get(data2, &x2, NULL, NULL, NULL);
- ELM_WIDGET_CHECK(obj) NULL;
- EINA_SAFETY_ON_NULL_RETURN_VAL(func, NULL);
- if (evas_object_smart_type_check(obj, "elm_layout"))
- data = elm_layout_signal_callback_del(obj, emission, source, func);
- else if (evas_object_smart_type_check(obj, "elm_icon"))
- {
- WRN("Deprecated function. This functionality on icon objects"
- " will be dropped on a next release.");
+ return x1 < x2 ? -1 : 1;
+}
- data = _elm_icon_signal_callback_del(obj, emission, source, func);
- }
+static Eina_List *_lines_split(Eina_List *children)
+{
+ Eo *c;
+ Eina_List *lines, *line, *l;
+ Evas_Coord yl, y, hl, h;
+ lines = line = NULL;
- return data;
-}
+ if (!children) return NULL;
+ EINA_LIST_FOREACH(children, l, c)
+ {
+ evas_object_geometry_get(c, NULL, &yl, NULL, &hl);
-/* Widget Shadow Begin */
+ /* remove child if its height == 0 */
+ if (hl != 0) break;
+ }
-typedef struct _Widget_Shadow
-{
- Eo *widget;
- Eo *surface;
- struct {
- double rx, ry, ox, oy, grow;
- int r, g, b, a;
- } props;
- Eina_Stringshare *code, *name;
-} Widget_Shadow;
+ EINA_LIST_FREE(children, c)
+ {
+ evas_object_geometry_get(c, NULL, &y, NULL, &h);
-static void _widget_shadow_update(Widget_Shadow *shadow);
+ /* remove child if its height == 0 */
+ if (h == 0) continue;
-static void
-_widget_shadow_del_cb(void *data, const Efl_Event *ev EINA_UNUSED)
-{
- Widget_Shadow *shadow = data;
+ if ((yl + (int)(0.25 * hl)) >= y)
+ {
+ //same line
+ line = eina_list_append(line,c);
+ }
+ else
+ {
+ // finish current line & start new
+ lines = eina_list_append(lines, line);
+ yl = y, hl = h;
+ line = eina_list_append(NULL, c);
+ }
+ }
- efl_del(shadow->surface);
- free(shadow);
+ return eina_list_append(lines, line);
}
+//
+//TIZEN_ONLY(20171114) atspi: integrate ewk_view with elementary accessibility
static void
-_widget_shadow_event_cb(void *data, const Efl_Event *ev EINA_UNUSED)
+_on_ewk_del(void *data, const Efl_Event *desc EINA_UNUSED)
{
- Widget_Shadow *shadow = data;
- _widget_shadow_update(shadow);
+ Eo *plug = data;
+ efl_del(plug);
}
+//
-EFL_CALLBACKS_ARRAY_DEFINE(widget_shadow_cb,
-{ EFL_EVENT_DEL, _widget_shadow_del_cb },
-{ EFL_GFX_ENTITY_EVENT_MOVE, _widget_shadow_event_cb },
-{ EFL_GFX_ENTITY_EVENT_RESIZE, _widget_shadow_event_cb },
-{ EFL_GFX_ENTITY_EVENT_STACK_CHANGED, _widget_shadow_event_cb },
-{ EFL_GFX_ENTITY_EVENT_HIDE, _widget_shadow_event_cb },
-{ EFL_GFX_ENTITY_EVENT_SHOW, _widget_shadow_event_cb })
-
-static Widget_Shadow *
-_widget_shadow_part_get(const Eo *part_obj)
+//TIZEN_ONLY(20170621) handle atspi proxy connection at runtime
+Eo *
+plug_type_proxy_get(Eo *obj, Evas_Object *widget)
{
- Elm_Part_Data *pd = efl_data_scope_get(part_obj, EFL_UI_WIDGET_PART_CLASS);
- Widget_Shadow *shadow;
- Eo *widget = pd->obj;
+ Eo *proxy = NULL;
+ const char *plug_id;
+ char *svcname, *svcnum;
- shadow = efl_key_data_get(widget, "__elm_shadow");
- if (!shadow)
+ if ((plug_id = evas_object_data_get(widget, "___PLUGID")) != NULL)
{
- shadow = calloc(1, sizeof(*shadow));
- if (!shadow) return NULL;
- shadow->widget = pd->obj;
- efl_key_data_set(widget, "__elm_shadow", shadow);
- efl_event_callback_array_add(widget, widget_shadow_cb(), shadow);
+ // TIZEN_ONLY(20160930) : endless recursion fix
+ efl_access_object_attribute_append(efl_super(obj, MY_CLASS), "___PlugID", plug_id);
+ efl_access_object_role_set(obj, EFL_ACCESS_ROLE_EMBEDDED);
+
+ proxy = evas_object_data_get(widget, "__widget_proxy");
+ // TIZEN_ONLY(20171109) : fix for invalid proxy object, when at-spi has been restarted
+ if (proxy)
+ {
+ if (!evas_object_data_get(proxy, "__proxy_invalid")) return proxy;
+ evas_object_data_del(widget, "__widget_proxy");
+ }
+ //
+
+ if (_elm_atspi_bridge_plug_id_split(plug_id, &svcname, &svcnum))
+ {
+ proxy = _elm_atspi_bridge_utils_proxy_create(obj, svcname, atoi(svcnum), ELM_ATSPI_PROXY_TYPE_PLUG);
+ evas_object_data_set(widget, "__widget_proxy", proxy);
+ efl_event_callback_add(widget, EFL_EVENT_DEL, _on_widget_del, proxy);
+ efl_event_callback_add(proxy, ELM_ATSPI_PROXY_EVENT_CONNECTED, _on_proxy_connected_cb, widget);
+ elm_atspi_bridge_utils_proxy_connect(proxy);
+ free(svcname);
+ free(svcnum);
+ }
}
- return shadow;
+
+ return proxy;
}
-static void
-_widget_shadow_update(Widget_Shadow *ws)
+EAPI Eo *
+elm_widget_atspi_plug_type_proxy_get(Evas_Object *obj)
{
- int l = 0, r = 0, t = 0, b = 0;
- Eina_Rect srect, wrect;
- char filter[1024];
+ Elm_Widget_Smart_Data *wd;
+ Evas_Object *widget;
+ Eina_List *l;
-#define FILTER_FMT \
- "a = buffer { 'alpha' }" \
- "grow { %f, dst = a, alphaonly = true }" \
- "blur { src = a, rx = %f, ry = %f, color = color(%d,%d,%d,%d) }"
+ wd = efl_data_scope_get(obj, EFL_UI_WIDGET_CLASS);
+ if (!wd) return NULL;
- if (!ws->surface)
+ Eo *proxy = NULL;
+ EINA_LIST_FOREACH(wd->subobjs, l, widget)
{
- ws->surface = efl_add(EFL_CANVAS_PROXY_CLASS, ws->widget);
- efl_gfx_fill_auto_set(ws->surface, 1);
- efl_canvas_proxy_source_clip_set(ws->surface, EINA_FALSE);
- efl_canvas_proxy_source_events_set(ws->surface, EINA_FALSE);
- efl_canvas_proxy_source_set(ws->surface, ws->widget);
+ proxy = plug_type_proxy_get(obj, widget);
+ if (proxy) break;
}
+ return proxy;
+}
+//
- if (!ws->code)
- {
- snprintf(filter, sizeof(filter), FILTER_FMT,
- ws->props.grow, ws->props.rx, ws->props.ry,
- ws->props.r, ws->props.g, ws->props.b, ws->props.a);
- }
- efl_gfx_filter_program_set(ws->surface,
- ws->code ? ws->code : filter,
- ws->name ? ws->name : "shadow");
- efl_gfx_filter_padding_get(ws->surface, &l, &r, &t, &b);
+//TIZEN_ONLY(20161107): enhance elm_atspi_accessible_can_highlight_set to set can_hihglight property to its children
+EAPI Eina_Bool
+_elm_widget_highlightable(Evas_Object *obj)
+{
+ Eo *parent;
- wrect = efl_gfx_entity_geometry_get(ws->widget);
- srect.x = wrect.x + (int) (-l + ws->props.ox);
- srect.y = wrect.y + (int) (-t + ws->props.oy);
- srect.w = wrect.w + (int) (l + r);
- srect.h = wrect.h + (int) (t + b);
+ Elm_Widget_Smart_Data *wd = efl_data_scope_get(obj, EFL_UI_WIDGET_CLASS);
+ if (!wd) return EINA_FALSE;
+ if (!wd->can_highlight) return EINA_FALSE;
- if ((!ws->props.a && !ws->code) ||
- !efl_gfx_entity_visible_get(ws->widget))
+ parent = efl_provider_find(efl_parent_get(obj), EFL_ACCESS_OBJECT_MIXIN);
+ while (parent && !efl_isa(parent, ELM_ATSPI_APP_OBJECT_CLASS))
{
- efl_gfx_entity_visible_set(ws->surface, EINA_FALSE);
- return;
+ //TIZEN_ONLY(20160929) : atspi: Improves how to find the can_highlight of the widget
+ if (!_elm_widget_can_highlight_get_by_class(parent)) return EINA_FALSE;
+ //
+ parent = efl_provider_find(efl_parent_get(parent), EFL_ACCESS_OBJECT_MIXIN);
}
-
- efl_canvas_object_clip_set(ws->surface, efl_canvas_object_clip_get(ws->widget));
- efl_canvas_group_member_add(efl_canvas_object_render_parent_get(ws->widget), ws->surface);
- efl_gfx_entity_geometry_set(ws->surface, srect);
- efl_gfx_stack_below(ws->surface, ws->widget);
- efl_gfx_entity_visible_set(ws->surface, EINA_TRUE);
+ return EINA_TRUE;
}
+//
-static void
-_elm_widget_shadow_update(Efl_Ui_Widget *obj)
+EAPI void
+elm_widget_scroll_item_valign_set(Evas_Object *obj,
+ const char *scroll_item_valign)
{
- Widget_Shadow *shadow = _widget_shadow_part_get(obj);
- _widget_shadow_update(shadow);
+ API_ENTRY return;
+ if (sd->scroll_item_valign) eina_stringshare_del(sd->scroll_item_valign);
+ if (!scroll_item_valign) sd->scroll_item_valign = NULL;
+ else sd->scroll_item_valign = eina_stringshare_add(scroll_item_valign);
}
-EOLIAN static void
-_efl_ui_widget_part_shadow_efl_gfx_blur_offset_set(Eo *obj, void *_pd EINA_UNUSED, double ox, double oy)
+EAPI const char*
+elm_widget_scroll_item_valign_get(const Evas_Object *obj)
{
- Widget_Shadow *shadow = _widget_shadow_part_get(obj);
- shadow->props.ox = ox;
- shadow->props.oy = oy;
- _widget_shadow_update(shadow);
+ API_ENTRY return NULL;
+ return sd->scroll_item_valign;
}
+//
-EOLIAN static void
-_efl_ui_widget_part_shadow_efl_gfx_blur_offset_get(const Eo *obj, void *_pd EINA_UNUSED, double *ox, double *oy)
+/* TIZEN_ONLY(20180504): add missing item class names and fix edje_class parse rule for legacy */
+const char *
+_elm_widget_item_legacy_type_get(const Evas_Object *obj)
{
- Widget_Shadow *shadow = _widget_shadow_part_get(obj);
- if (ox) *ox = shadow->props.ox;
- if (oy) *oy = shadow->props.oy;
-}
+ const char *ret;
+ int i;
-EOLIAN static void
-_efl_ui_widget_part_shadow_efl_gfx_blur_radius_set(Eo *obj, void *_pd EINA_UNUSED, double rx, double ry)
-{
- Widget_Shadow *shadow = _widget_shadow_part_get(obj);
- shadow->props.rx = rx;
- shadow->props.ry = ry;
- _widget_shadow_update(shadow);
-}
+ ret = efl_class_name_get(efl_class_get(obj));
-EOLIAN static void
-_efl_ui_widget_part_shadow_efl_gfx_blur_radius_get(const Eo *obj, void *_pd EINA_UNUSED, double *rx, double *ry)
-{
- Widget_Shadow *shadow = _widget_shadow_part_get(obj);
- if (rx) *rx = shadow->props.rx;
- if (ry) *ry = shadow->props.ry;
-}
+ /* If the given widget is created for legacy,
+ * convert type name to legacy. */
+ for (i = 0; legacy_type_table[i][0] ; i++)
+ {
+ if (eina_streq(ret, legacy_type_table[i][0]))
+ return legacy_type_table[i][1];
+ }
-EOLIAN static void
-_efl_ui_widget_part_shadow_efl_gfx_color_color_set(Eo *obj, void *_pd EINA_UNUSED, int r, int g, int b, int a)
-{
- Widget_Shadow *shadow = _widget_shadow_part_get(obj);
- shadow->props.r = r;
- shadow->props.g = g;
- shadow->props.b = b;
- shadow->props.a = a;
- _widget_shadow_update(shadow);
+ return ret;
}
+/* END */
EOLIAN static void
-_efl_ui_widget_part_shadow_efl_gfx_color_color_get(const Eo *obj, void *_pd EINA_UNUSED, int *r, int *g, int *b, int *a)
+_efl_ui_widget_focus_disabled_handle(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
{
- Widget_Shadow *shadow = _widget_shadow_part_get(obj);
- if (r) *r = shadow->props.r;
- if (g) *g = shadow->props.g;
- if (b) *b = shadow->props.b;
- if (a) *a = shadow->props.a;
+ efl_ui_widget_focus_tree_unfocusable_handle(obj);
}
-EOLIAN static void
-_efl_ui_widget_part_shadow_efl_gfx_blur_grow_set(Eo *obj, void *_pd EINA_UNUSED, double radius)
+EOLIAN static unsigned int
+_efl_ui_widget_focus_order_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
{
- Widget_Shadow *shadow = _widget_shadow_part_get(obj);
- shadow->props.grow = radius;
- _widget_shadow_update(shadow);
+ return sd->focus_order;
}
-EOLIAN static double
-_efl_ui_widget_part_shadow_efl_gfx_blur_grow_get(const Eo *obj, void *_pd EINA_UNUSED)
+EOLIAN static Evas_Object*
+_efl_ui_widget_newest_focus_order_get(const Eo *obj, Elm_Widget_Smart_Data *sd, unsigned int *newest_focus_order, Eina_Bool can_focus_only)
{
- Widget_Shadow *shadow = _widget_shadow_part_get(obj);
- return shadow->props.grow;
-}
+ const Eina_List *l;
+ Evas_Object *child, *cur, *best;
-EOLIAN static void
-_efl_ui_widget_part_shadow_efl_gfx_filter_filter_program_set(Eo *obj, void *_pd EINA_UNUSED, const char *code, const char *name)
-{
- Widget_Shadow *ws = _widget_shadow_part_get(obj);
- eina_stringshare_replace(&ws->code, code);
- eina_stringshare_replace(&ws->name, name);
- _widget_shadow_update(ws);
-}
+ if (!evas_object_visible_get(obj)
+ || (elm_widget_disabled_get(obj))
+ || (elm_widget_tree_unfocusable_get(obj)))
+ return NULL;
-EOLIAN static void
-_efl_ui_widget_part_shadow_efl_gfx_filter_filter_program_get(const Eo *obj, void *_pd EINA_UNUSED, const char **code, const char **name)
-{
- Widget_Shadow *ws = _widget_shadow_part_get(obj);
- efl_gfx_filter_program_get(ws->surface, code, name);
-}
+ 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;
-EOLIAN static void
-_efl_ui_widget_part_shadow_efl_gfx_filter_filter_source_set(Eo *obj, void *_pd EINA_UNUSED, const char *name, Efl_Gfx_Entity *source)
-{
- Widget_Shadow *ws = _widget_shadow_part_get(obj);
- _widget_shadow_update(ws);
- efl_gfx_filter_source_set(ws->surface, name, source);
+ cur = efl_ui_widget_newest_focus_order_get
+ (child, newest_focus_order, can_focus_only);
+ if (!cur) continue;
+ best = cur;
+ }
+ return best;
}
-EOLIAN static Efl_Gfx_Entity *
-_efl_ui_widget_part_shadow_efl_gfx_filter_filter_source_get(const Eo *obj, void *_pd EINA_UNUSED, const char *name)
+EOLIAN static Eina_Bool
+_efl_ui_widget_focus_next_manager_is(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
{
- Widget_Shadow *ws = _widget_shadow_part_get(obj);
- return efl_gfx_filter_source_get(ws->surface, name);
+ 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;
}
-EOLIAN static void
-_efl_ui_widget_part_shadow_efl_gfx_filter_filter_data_set(Eo *obj, void *_pd EINA_UNUSED, const char *name, const char *value, Eina_Bool execute)
+static Eina_Bool
+_efl_ui_widget_focus_direction_manager_is(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
{
- Widget_Shadow *ws = _widget_shadow_part_get(obj);
- _widget_shadow_update(ws);
- efl_gfx_filter_data_set(ws->surface, name, value, execute);
+ 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;
}
-
+//
+//TIZEN_ONLY(20180607): Restore legacy focus
EOLIAN static void
-_efl_ui_widget_part_shadow_efl_gfx_filter_filter_data_get(const Eo *obj, void *_pd EINA_UNUSED, const char *name, const char **value, Eina_Bool *execute)
+_efl_ui_widget_focus_mouse_up_handle(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
{
- Widget_Shadow *ws = _widget_shadow_part_get(obj);
- efl_gfx_filter_data_get(ws->surface, name, value, execute);
-}
+ if (!obj) return;
+ if (!_is_focusable(obj)) return;
-EOLIAN static void
-_efl_ui_widget_part_shadow_efl_gfx_filter_filter_padding_get(const Eo *obj, void *_pd EINA_UNUSED, int *l, int *r, int *t, int *b)
+ efl_ui_widget_focus_steal(obj, NULL);
+}
+EOLIAN static Elm_Object_Item*
+_efl_ui_widget_focused_item_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
{
- Widget_Shadow *ws = _widget_shadow_part_get(obj);
- efl_gfx_filter_padding_get(ws->surface, l, r, t, b);
+ return NULL;
}
EOLIAN static void
-_efl_ui_widget_part_shadow_efl_gfx_filter_filter_state_set(Eo *obj, void *_pd EINA_UNUSED, const char *cur_state, double cur_val, const char *next_state, double next_val, double pos)
+_efl_ui_widget_interest_region_mode_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd, Elm_Focus_Region_Show_Mode mode)
{
- Widget_Shadow *ws = _widget_shadow_part_get(obj);
- efl_gfx_filter_state_set(ws->surface, cur_state, cur_val, next_state, next_val, pos);
+ _pd->focus_region_show_mode = mode;
}
-EOLIAN static void
-_efl_ui_widget_part_shadow_efl_gfx_filter_filter_state_get(const Eo *obj, void *_pd EINA_UNUSED, const char **cur_state, double *cur_val, const char **next_state, double *next_val, double *pos)
+EOLIAN static Elm_Focus_Region_Show_Mode
+_efl_ui_widget_interest_region_mode_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd)
{
- Widget_Shadow *ws = _widget_shadow_part_get(obj);
- efl_gfx_filter_state_get(ws->surface, cur_state, cur_val, next_state, next_val, pos);
+ return _pd->focus_region_show_mode;
}
-#include "efl_ui_widget_part_shadow.eo.c"
-
-/* Widget Shadow End */
-
-
-/* Efl.Part implementation */
-EOLIAN static Efl_Object *
-_efl_ui_widget_efl_part_part_get(const Eo *obj, Elm_Widget_Smart_Data *wd EINA_UNUSED, const char *part)
+//TIZEN_ONLY(20160929) : atspi: Improves how to find the can_highlight of the widget
+static Eina_Bool
+_elm_widget_can_highlight_get_by_class(Eo *obj)
{
- if (eina_streq(part, "background"))
- return ELM_PART_IMPLEMENT(EFL_UI_WIDGET_PART_BG_CLASS, obj, part);
- else if (eina_streq(part, "shadow"))
- return ELM_PART_IMPLEMENT(EFL_UI_WIDGET_PART_SHADOW_CLASS, obj, part);
- return ELM_PART_IMPLEMENT(EFL_UI_WIDGET_PART_CLASS, obj, part);
+ if (efl_isa(obj, ELM_WIDGET_ITEM_CLASS))
+ {
+ Elm_Widget_Item_Data *id = efl_data_scope_get(obj, ELM_WIDGET_ITEM_CLASS);
+ if (!id) return EINA_FALSE;
+ if (!id->can_highlight) return EINA_FALSE;
+ }
+ else
+ {
+ Elm_Widget_Smart_Data *wd = efl_data_scope_get(obj, EFL_UI_WIDGET_CLASS);
+ if (!wd) return EINA_FALSE;
+ if (!wd->can_highlight) return EINA_FALSE;
+ }
+ return EINA_TRUE;
}
+//
-EOLIAN static void \
-_efl_ui_widget_part_efl_object_destructor(Eo *obj, Elm_Part_Data *pd)
+//TIZEN_ONLY(20161107): enhance elm_atspi_accessible_can_highlight_set to set can_hihglight property to its children
+EAPI Eina_Bool
+_elm_widget_item_highlightable(Elm_Object_Item *item)
{
- ELM_PART_HOOK;
- eina_tmpstr_del(pd->part);
- efl_destructor(efl_super(obj, EFL_UI_WIDGET_PART_CLASS));
-}
-
-#include "efl_ui_widget_part.eo.c"
-
-/* Efl.Part end */
-
-/* Efl.Part Bg implementation */
+ Eo *parent;
-Efl_Canvas_Object *
-_efl_ui_widget_bg_get(const Efl_Ui_Widget *obj)
-{
- Elm_Widget_Smart_Data *sd = efl_data_scope_get(obj, MY_CLASS);
- Evas_Object *bg_obj = sd->bg;
+ Elm_Widget_Item_Data *id = efl_data_scope_get(item, ELM_WIDGET_ITEM_CLASS);
+ if (!id) return EINA_FALSE;
+ if (!id->can_highlight) return EINA_FALSE;
- if (!bg_obj)
+ parent = efl_provider_find(efl_parent_get(item), EFL_ACCESS_OBJECT_MIXIN);
+ while (parent && !efl_isa(parent, ELM_ATSPI_APP_OBJECT_CLASS))
{
- bg_obj = efl_add(EFL_UI_BG_CLASS, obj);
- EINA_SAFETY_ON_NULL_RETURN_VAL(bg_obj, NULL);
- sd->bg = bg_obj;
- efl_canvas_group_member_add(obj, sd->bg);
- evas_object_stack_below(sd->bg, sd->resize_obj);
- _smart_reconfigure(sd);
+ //TIZEN_ONLY(20160929) : atspi: Improves how to find the can_highlight of the widget
+ if (!_elm_widget_can_highlight_get_by_class(parent)) return EINA_FALSE;
+ //
+ parent = efl_provider_find(efl_parent_get(parent), EFL_ACCESS_OBJECT_MIXIN);
}
-
- return bg_obj;
-}
-
-static inline Efl_Canvas_Object *
-efl_ui_widget_part_bg_get(const Eo *part_obj)
-{
- Elm_Part_Data *pd = efl_data_scope_get(part_obj, EFL_UI_WIDGET_PART_CLASS);
- return _efl_ui_widget_bg_get(pd->obj);
+ return EINA_TRUE;
}
+//
-EOLIAN static Eina_Bool
-_efl_ui_widget_part_bg_efl_file_file_set(Eo *obj, void *pd EINA_UNUSED, const char *file, const char *key)
+//TIZEN_ONLY(20170206): Add check the object is in the scroller content size
+static Eina_Bool
+_accessible_object_on_scroll_is(Eo* obj)
{
- Evas_Object *bg_obj = efl_ui_widget_part_bg_get(obj);
+ /* in case of genlist item, the item->view is NULL if item is unrealized.
+ this function is used to check if obj could have HIGHLIGHTABLE or not.
+ the unrealized genlist item should have HIGHLIGHTABLE state.
+ so if obj is NULL return EINA_TRUE */
+ if(!obj) return EINA_TRUE;
- return efl_file_set(bg_obj, file, key);
-}
+ Evas_Object *target = obj;
+ Evas_Object *parent = NULL;
+ Evas_Coord x, y, w, h, wx, wy, ww = 0, wh = 0, nx = 0, ny = 0;
-EOLIAN static void
-_efl_ui_widget_part_bg_efl_file_file_get(const Eo *obj, void *pd EINA_UNUSED, const char **file, const char **key)
-{
- Evas_Object *bg_obj = efl_ui_widget_part_bg_get(obj);
+ evas_object_geometry_get(target, &x, &y ,&w, &h);
- efl_file_get(bg_obj, file, key);
-}
+ if (elm_widget_is(target))
+ parent = elm_widget_parent_get(target);
+ else
+ parent = elm_widget_parent_widget_get(target);
-EOLIAN static void
-_efl_ui_widget_part_bg_efl_gfx_color_color_set(Eo *obj, void *pd EINA_UNUSED, int r, int g, int b, int a)
-{
- Evas_Object *bg_obj = efl_ui_widget_part_bg_get(obj);
+ while (parent)
+ {
+ if (efl_isa(parent, ELM_INTERFACE_SCROLLABLE_MIXIN))
+ {
+ evas_object_geometry_get(parent, &wx, &wy, NULL, NULL);
+ elm_interface_scrollable_content_size_get(parent, &ww, &wh);
+ elm_interface_scrollable_content_pos_get(parent, &nx, &ny);
- efl_gfx_color_set(bg_obj, r, g, b, a);
-}
+ /* widget implements scrollable interface but does not use scoller
+ in this case, use widget geometry */
+ if (ww == 0 || wh == 0)
+ {
+ INF("%s is zero sized scrollable content", efl_class_name_get(efl_class_get(parent)));
+ evas_object_geometry_get(parent, NULL, NULL, &ww, &wh);
+ }
-EOLIAN static void
-_efl_ui_widget_part_bg_efl_gfx_color_color_get(const Eo *obj, void *pd EINA_UNUSED, int *r, int *g, int *b, int *a)
-{
- Evas_Object *bg_obj = efl_ui_widget_part_bg_get(obj);
+ wx -= nx;
+ wy -= ny;
- efl_gfx_color_get(bg_obj, r, g, b, a);
-}
+ if (((wx < x) && (wx + ww < x)) || ((wx > x + w) && (wx + ww > x + w)) ||
+ ((wy < y) && (wy + wh < y)) || ((wy > y + h) && (wy + wh > y + h)))
+ return EINA_FALSE;
-EOLIAN static void
-_efl_ui_widget_part_bg_efl_gfx_image_scale_type_set(Eo *obj, void *pd EINA_UNUSED, Efl_Gfx_Image_Scale_Type scale_type)
-{
- Evas_Object *bg_obj = efl_ui_widget_part_bg_get(obj);
+ break;
+ }
+ parent = elm_widget_parent_get(parent);
+ }
- efl_gfx_image_scale_type_set(bg_obj, scale_type);
+ return EINA_TRUE;
}
+//
-EOLIAN static Efl_Gfx_Image_Scale_Type
-_efl_ui_widget_part_bg_efl_gfx_image_scale_type_get(const Eo *obj, void *pd EINA_UNUSED)
-
+//TIZEN_ONLY(20180607): Restore legacy focus
+/**
+ * @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)
{
- Evas_Object *bg_obj = efl_ui_widget_part_bg_get(obj);
+ API_ENTRY return;
+ Elm_Focus_Move_Policy focus_move_policy = elm_config_focus_move_policy_get();
- return efl_gfx_image_scale_type_get(bg_obj);
+ if (efl_ui_widget_focus_move_policy_automatic_get(obj) &&
+ (sd->focus_move_policy != focus_move_policy))
+ {
+ sd->focus_move_policy = focus_move_policy;
+ }
}
-#include "efl_ui_widget_part_bg.eo.c"
-
-/* Efl.Part Bg end */
-
-
-/* Internal EO APIs and hidden overrides */
-
-EFL_FUNC_BODY_CONST(efl_ui_widget_default_content_part_get, const char *, NULL)
-EFL_FUNC_BODY_CONST(efl_ui_widget_default_text_part_get, const char *, NULL)
-
-ELM_PART_CONTENT_DEFAULT_GET(efl_ui_widget, NULL)
-ELM_PART_TEXT_DEFAULT_GET(efl_ui_widget, NULL)
-
-/***********************************************************************************
- * TIZEN_ONLY_FEATURE: apply Tizen's color_class features. *
- ***********************************************************************************/
-/* Internal EO APIs and hidden overrides */
-EAPI EFL_FUNC_BODYV(elm_widget_class_color_set, Eina_Bool, EINA_FALSE,
- EFL_FUNC_CALL(color_class, r, g, b, a),
- const char *color_class, int r, int g, int b, int a)
-EAPI EFL_FUNC_BODYV(elm_widget_class_color_get, Eina_Bool, EINA_FALSE,
- EFL_FUNC_CALL(color_class, r, g, b, a),
- const char *color_class, int *r, int *g, int *b, int *a)
-EAPI EFL_FUNC_BODYV(elm_widget_class_color2_set, Eina_Bool, EINA_FALSE,
- EFL_FUNC_CALL(color_class, r, g, b, a),
- const char *color_class, int r, int g, int b, int a)
-EAPI EFL_FUNC_BODYV(elm_widget_class_color2_get, Eina_Bool, EINA_FALSE,
- EFL_FUNC_CALL(color_class, r, g, b, a),
- const char *color_class, int *r, int *g, int *b, int *a)
-EAPI EFL_FUNC_BODYV(elm_widget_class_color3_set, Eina_Bool, EINA_FALSE,
- EFL_FUNC_CALL(color_class, r, g, b, a),
- const char *color_class, int r, int g, int b, int a)
-EAPI EFL_FUNC_BODYV(elm_widget_class_color3_get, Eina_Bool, EINA_FALSE,
- EFL_FUNC_CALL(color_class, r, g, b, a),
- const char *color_class, int *r, int *g, int *b, int *a)
-EAPI EFL_VOID_FUNC_BODYV(elm_widget_class_color_del,
- EFL_FUNC_CALL(color_class),
- const char *color_class)
-EAPI EFL_VOID_FUNC_BODY(elm_widget_class_color_clear)
-
-static Eina_Bool _elm_widget_class_color_set(Eo *obj, Elm_Widget_Smart_Data *sd EINA_UNUSED, const char *color_class, int r, int g, int b, int a);
-static Eina_Bool _elm_widget_class_color_get(Eo *obj, Elm_Widget_Smart_Data *sd EINA_UNUSED, const char *color_class, int *r, int *g, int *b, int *a);
-static Eina_Bool _elm_widget_class_color2_set(Eo *obj, Elm_Widget_Smart_Data *sd EINA_UNUSED, const char *color_class, int r, int g, int b, int a);
-static Eina_Bool _elm_widget_class_color2_get(Eo *obj, Elm_Widget_Smart_Data *sd EINA_UNUSED, const char *color_class, int *r, int *g, int *b, int *a);
-static Eina_Bool _elm_widget_class_color3_set(Eo *obj, Elm_Widget_Smart_Data *sd EINA_UNUSED, const char *color_class, int r, int g, int b, int a);
-static Eina_Bool _elm_widget_class_color3_get(Eo *obj, Elm_Widget_Smart_Data *sd EINA_UNUSED, const char *color_class, int *r, int *g, int *b, int *a);
-static void _elm_widget_class_color_del(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, const char *color_class);
-static void _elm_widget_class_color_clear(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd);
-/*******
- * END *
- *******/
-
+EOLIAN static void
+_efl_ui_widget_focus_reconfigure(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
+{
+ const Eina_List *l;
+ Evas_Object *child;
+ API_ENTRY return;
-#define EFL_UI_WIDGET_EXTRA_OPS \
- EFL_CANVAS_GROUP_ADD_DEL_OPS(efl_ui_widget), \
- ELM_PART_CONTENT_DEFAULT_OPS(efl_ui_widget), \
- ELM_PART_TEXT_DEFAULT_OPS(efl_ui_widget), \
- EFL_OBJECT_OP_FUNC(efl_dbg_info_get, _efl_ui_widget_efl_object_dbg_info_get), \
-/*********************************************************************************** \
- * TIZEN_ONLY_FEATURE: apply Tizen's color_class features. * \
- ***********************************************************************************/ \
- EFL_OBJECT_OP_FUNC(elm_widget_class_color_set, _elm_widget_class_color_set), \
- EFL_OBJECT_OP_FUNC(elm_widget_class_color_get, _elm_widget_class_color_get), \
- EFL_OBJECT_OP_FUNC(elm_widget_class_color2_set, _elm_widget_class_color2_set), \
- EFL_OBJECT_OP_FUNC(elm_widget_class_color2_get, _elm_widget_class_color2_get), \
- EFL_OBJECT_OP_FUNC(elm_widget_class_color3_set, _elm_widget_class_color3_set), \
- EFL_OBJECT_OP_FUNC(elm_widget_class_color3_get, _elm_widget_class_color3_get), \
- EFL_OBJECT_OP_FUNC(elm_widget_class_color_del, _elm_widget_class_color_del), \
- EFL_OBJECT_OP_FUNC(elm_widget_class_color_clear, _elm_widget_class_color_clear)
+ EINA_LIST_FOREACH(sd->subobjs, l, child)
+ {
+ if (elm_widget_is(child))
+ efl_ui_widget_focus_reconfigure(child);
+ }
-/*******
- * END *
- *******/
+ if (sd->hover_obj) efl_ui_widget_focus_reconfigure(sd->hover_obj);
+ _elm_widget_focus_move_policy_reload(obj);
+}
+//
//TIZEN_ONLY(20160329): widget: improve accessible_at_point getter (a8aff0423202b9a55dbb3843205875226678fbd6)
static void
eina_stringshare_del(buf); \
return int_ret
-Eina_Bool
-_elm_widget_item_color_class_update(Elm_Widget_Item_Data *sd)
+Eina_Bool
+_elm_widget_item_color_class_update(Elm_Widget_Item_Data *sd)
+{
+ ELM_COLOR_CLASS_UPDATE(sd->view, sd->color_classes, (!sd) || (!sd->color_classes) || (!sd->view));
+}
+
+/* Internal EO API */
+static Eina_Bool
+_elm_widget_item_class_color_set(Eo *obj, Elm_Widget_Item_Data *sd, const char *color_class, int r, int g, int b, int a)
+{
+ ELM_COLOR_CLASS_SET_START(obj, r, g, b, a);
+
+ int_ret &= _elm_widget_item_color_class_update(sd);
+
+ ELM_COLOR_CLASS_SET_END();
+}
+
+/* Internal EO API */
+static Eina_Bool
+_elm_widget_item_class_color_get(const Eo *obj, Elm_Widget_Item_Data *sd, const char *color_class, int *r, int *g, int *b, int *a)
+{
+ ELM_COLOR_CLASS_GET(obj, r, g, b, a);
+}
+
+/* Internal EO API */
+static Eina_Bool
+_elm_widget_item_class_color2_set(Eo *obj, Elm_Widget_Item_Data *sd, const char *color_class, int r, int g, int b, int a)
+{
+ ELM_COLOR_CLASS_SET_START(obj, r2, g2, b2, a2);
+
+ int_ret &= _elm_widget_item_color_class_update(sd);
+
+ ELM_COLOR_CLASS_SET_END();
+}
+
+/* Internal EO API */
+static Eina_Bool
+_elm_widget_item_class_color2_get(const Eo *obj, Elm_Widget_Item_Data *sd, const char *color_class, int *r, int *g, int *b, int *a)
+{
+ ELM_COLOR_CLASS_GET(obj, r2, g2, b2, a2);
+}
+
+/* Internal EO API */
+static Eina_Bool
+_elm_widget_item_class_color3_set(Eo *obj, Elm_Widget_Item_Data *sd, const char *color_class, int r, int g, int b, int a)
+{
+ ELM_COLOR_CLASS_SET_START(obj, r3, g3, b3, a3);
+
+ int_ret &= _elm_widget_item_color_class_update(sd);
+
+ ELM_COLOR_CLASS_SET_END();
+}
+
+/* Internal EO API */
+static Eina_Bool
+_elm_widget_item_class_color3_get(const Eo *obj, Elm_Widget_Item_Data *sd, const char *color_class, int *r, int *g, int *b, int *a)
+{
+ ELM_COLOR_CLASS_GET(obj, r3, g3, b3, a3);
+}
+
+/* Internal EO API */
+static Evas_Object *
+_elm_widget_item_edje_get(const Eo *obj, Elm_Widget_Item_Data *sd)
+{
+ if (!sd)
+ sd = efl_data_scope_get(obj, ELM_WIDGET_ITEM_CLASS);
+
+ if (efl_isa(sd->view, EFL_UI_LAYOUT_CLASS))
+ return elm_layout_edje_get(sd->view);
+ else if (efl_isa(sd->view, EFL_CANVAS_LAYOUT_CLASS))
+ return sd->view;
+
+ return NULL;
+}
+
+/* Internal EO API */
+static void
+_elm_widget_item_class_color_del(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *sd, const char *color_class)
+{
+ Eina_Stringshare *buf;
+ Evas_Object *edje;
+ Edje_Color_Class *cc = NULL;
+
+ if (!color_class) return;
+
+ buf = _elm_widget_edje_class_get(obj, NULL, color_class);
+ eina_hash_del(sd->color_classes, buf, cc);
+
+ edje = _elm_widget_item_edje_get(obj, sd);
+ if (edje)
+ edje_object_color_class_del(edje, buf);
+
+ eina_stringshare_del(buf);
+}
+
+/* Internal EO API */
+static void
+_elm_widget_item_class_color_clear(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *sd)
+{
+ Evas_Object *edje;
+ ELM_SAFE_FREE(sd->color_classes, eina_hash_free);
+
+ edje = _elm_widget_item_edje_get(obj, sd);
+ if (!edje) return;
+
+ edje_object_color_class_clear(edje);
+}
+
+/* Internal EO APIs and hidden overrides */
+EAPI EFL_FUNC_BODYV(elm_widget_item_class_color_set, Eina_Bool, EINA_FALSE,
+ EFL_FUNC_CALL(color_class, r, g, b, a),
+ const char *color_class, int r, int g, int b, int a)
+EAPI EFL_FUNC_BODYV(elm_widget_item_class_color_get, Eina_Bool, EINA_FALSE,
+ EFL_FUNC_CALL(color_class, r, g, b, a),
+ const char *color_class, int *r, int *g, int *b, int *a)
+EAPI EFL_FUNC_BODYV(elm_widget_item_class_color2_set, Eina_Bool, EINA_FALSE,
+ EFL_FUNC_CALL(color_class, r, g, b, a),
+ const char *color_class, int r, int g, int b, int a)
+EAPI EFL_FUNC_BODYV(elm_widget_item_class_color2_get, Eina_Bool, EINA_FALSE,
+ EFL_FUNC_CALL(color_class, r, g, b, a),
+ const char *color_class, int *r, int *g, int *b, int *a)
+EAPI EFL_FUNC_BODYV(elm_widget_item_class_color3_set, Eina_Bool, EINA_FALSE,
+ EFL_FUNC_CALL(color_class, r, g, b, a),
+ const char *color_class, int r, int g, int b, int a)
+EAPI EFL_FUNC_BODYV(elm_widget_item_class_color3_get, Eina_Bool, EINA_FALSE,
+ EFL_FUNC_CALL(color_class, r, g, b, a),
+ const char *color_class, int *r, int *g, int *b, int *a)
+EAPI EFL_VOID_FUNC_BODYV(elm_widget_item_class_color_del,
+ EFL_FUNC_CALL(color_class),
+ const char *color_class)
+EAPI EFL_VOID_FUNC_BODY(elm_widget_item_class_color_clear)
+
+#define ELM_WIDGET_ITEM_EXTRA_OPS \
+ EFL_OBJECT_OP_FUNC(elm_widget_item_class_color_set, _elm_widget_item_class_color_set), \
+ EFL_OBJECT_OP_FUNC(elm_widget_item_class_color_get, _elm_widget_item_class_color_get), \
+ EFL_OBJECT_OP_FUNC(elm_widget_item_class_color2_set, _elm_widget_item_class_color2_set), \
+ EFL_OBJECT_OP_FUNC(elm_widget_item_class_color2_get, _elm_widget_item_class_color2_get), \
+ EFL_OBJECT_OP_FUNC(elm_widget_item_class_color3_set, _elm_widget_item_class_color3_set), \
+ EFL_OBJECT_OP_FUNC(elm_widget_item_class_color3_get, _elm_widget_item_class_color3_get), \
+ EFL_OBJECT_OP_FUNC(elm_widget_item_class_color_del, _elm_widget_item_class_color_del), \
+ EFL_OBJECT_OP_FUNC(elm_widget_item_class_color_clear, _elm_widget_item_class_color_clear)
+
+/*******
+ * END *
+ *******/
+
+//TIZEN_ONLY(20180607): Restore legacy focus
+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 = efl_ui_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))
+ efl_ui_widget_focus_steal(newest, NULL);
+ else
+ {
+ if (sd2->resize_obj && _is_focused(sd2->resize_obj))
+ efl_ui_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))
+ {
+ efl_ui_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);
+ }
+ }
+ }
+}
+
+/**
+ * @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
+_efl_ui_widget_focus_custom_chain_set(Eo *obj, Elm_Widget_Smart_Data *sd, Eina_List *objs)
+{
+ if (!_elm_widget_focus_chain_manager_is(obj)) return;
+
+ efl_ui_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*
+_efl_ui_widget_focus_custom_chain_get(const 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
+_efl_ui_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
+_efl_ui_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
+_efl_ui_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
+_efl_ui_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;
+ efl_ui_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())
+ efl_ui_widget_focus_steal(target, target_item);
+
+ _elm_access_highlight_set(target);
+ elm_widget_focus_region_show(target);
+ }
+ else efl_ui_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
+_efl_ui_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 = efl_ui_widget_focused_object_get(obj);
+
+ if (efl_ui_widget_focus_direction_get
+ (obj, current_focused, degree, &target, &target_item, &weight))
+ {
+ efl_ui_widget_focus_steal(target, NULL);
+ return EINA_TRUE;
+ }
+
+ return EINA_FALSE;
+}
+
+/**
+ * @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
+_efl_ui_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 = efl_ui_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
+ */
+EOLIAN static Eina_Bool
+_efl_ui_widget_focus_list_direction_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED, const Evas_Object *base, const Eina_List *items, void* 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_func_type)list_data_get)(l);
+ if (cur && _elm_widget_is(cur))
+ efl_ui_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
+_efl_ui_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 = efl_ui_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
+ */
+EOLIAN static Eina_Bool
+_efl_ui_widget_focus_list_next_get(const Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED, const Eina_List *items, void * 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 = efl_ui_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 = efl_ui_widget_focus_next_item_get(focused_object, dir);
+ if (*next_item)
+ *next = elm_object_item_widget_get(*next_item);
+ else
+ *next = efl_ui_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 (efl_ui_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))
+ {
+ for (; l; l = list_next(l))
+ {
+ Evas_Object *cur = ((list_data_get_func_type)list_data_get)(l);
+ if (ELM_WIDGET_FOCUS_GET(cur)) break;
+ }
+
+ /* 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_func_type)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 (efl_ui_widget_focus_next_get(cur, dir, &tmp, &tmp_item))
+ {
+ *next = tmp;
+ *next_item = tmp_item;
+ return EINA_TRUE;
+ }
+ else if ((dir == ELM_FOCUS_UP)
+ || (dir == ELM_FOCUS_DOWN)
+ || (dir == ELM_FOCUS_RIGHT)
+ || (dir == ELM_FOCUS_LEFT))
+ {
+ if (tmp && _is_focused(cur))
+ {
+ *next = tmp;
+ *next_item = tmp_item;
+ return EINA_FALSE;
+ }
+ }
+ else if ((tmp) && (!to_focus))
+ {
+ to_focus = tmp;
+ to_focus_item = tmp_item;
+ }
+ }
+
+ 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_func_type)list_data_get)(l);
+
+ if (elm_widget_parent_get(cur) != obj)
+ continue;
+
+ /* Try Focus cycle in subitem */
+ efl_ui_widget_focus_next_get(cur, dir, &tmp, &tmp_item);
+ if (tmp)
+ {
+ *next = tmp;
+ *next_item = tmp_item;
+ return EINA_FALSE;
+ }
+ }
+
+ *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_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*
+_efl_ui_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
+_efl_ui_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*
+_efl_ui_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;
+
+}
+
+EOLIAN static void
+_efl_ui_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;
+}
+
+EAPI void
+elm_widget_focus_set(Eo *obj, Eina_Bool focus)
+{
+ ELM_WIDGET_DATA_GET_OR_RETURN(obj, sd);
+ if (!sd->focused)
+ {
+ focus_order++;
+ sd->focus_order = focus_order;
+ sd->focused = EINA_TRUE;
+ efl_ui_focus_object_on_focus_update(obj);
+ }
+
+ if (focus)
+ {
+ if ((_is_focusable(sd->resize_obj)) &&
+ (!elm_widget_disabled_get(sd->resize_obj)))
+ {
+ elm_widget_focus_set(sd->resize_obj, focus);
+ }
+ else
+ {
+ const Eina_List *l;
+ Evas_Object *child;
+
+ EINA_LIST_FOREACH(sd->subobjs, l, child)
+ {
+ if (!_elm_widget_is(child)) continue;
+ if ((_is_focusable(child)) &&
+ (!elm_widget_disabled_get(child)))
+ {
+ elm_widget_focus_set(child, focus);
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ const Eina_List *l;
+ Evas_Object *child;
+
+ EINA_LIST_REVERSE_FOREACH(sd->subobjs, l, child)
+ {
+ if (!_elm_widget_is(child)) continue;
+ if ((_is_focusable(child)) &&
+ (!elm_widget_disabled_get(child)))
+ {
+ elm_widget_focus_set(child, focus);
+ break;
+ }
+ }
+ }
+}
+
+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))
+ {
+ efl_ui_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))
+ {
+ efl_ui_widget_focused_object_clear(child);
+ break;
+ }
+ }
+ }
+}
+
+EOLIAN static void
+_efl_ui_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)
+ efl_ui_focus_object_on_focus_update(obj);
+}
+
+EOLIAN static void
+_efl_ui_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)))
+ efl_ui_widget_focused_object_clear(parent);
+ else
+ {
+ parent2 = elm_widget_parent_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);
+ efl_ui_focus_object_on_focus_update(obj);
+}
+
+EOLIAN static void
+_efl_ui_widget_focus_restore(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
+{
+ Evas_Object *newest = NULL;
+ unsigned int newest_focus_order = 0;
+
+ newest = efl_ui_widget_newest_focus_order_get(obj, &newest_focus_order, EINA_TRUE);
+ if (newest)
+ _parents_on_focus(newest);
+}
+//END
+
+
+static void
+_elm_widget_disabled_eval(const Evas_Object *obj, Eina_Bool disabled)
+{
+ const Eina_List *l;
+ Evas_Object *child;
+ ELM_WIDGET_DATA_GET(obj, sd);
+
+ EINA_LIST_FOREACH(sd->subobjs, l, child)
+ {
+ if (elm_widget_is(child))
+ {
+ //TIZEN_ONLY(20180607): Restore legacy focus
+ if (elm_widget_is_legacy(obj))
+ efl_ui_widget_focus_disabled_handle((Evas_Object *)obj);
+ //
+ efl_ui_widget_on_disabled_update(child, disabled);
+ _elm_widget_disabled_eval(child, disabled);
+ }
+ }
+}
+
+static void
+elm_widget_disabled_internal(Eo *obj, Eina_Bool disabled)
{
- ELM_COLOR_CLASS_UPDATE(sd->view, sd->color_classes, (!sd) || (!sd->color_classes) || (!sd->view));
+ if (!disabled && elm_widget_disabled_get(elm_widget_parent_get(obj)))
+ return;
+ //TIZEN_ONLY(20180607): Restore legacy focus
+ if (elm_widget_is_legacy(obj))
+ efl_ui_widget_focus_disabled_handle(obj);
+ //
+ efl_ui_widget_on_disabled_update(obj, disabled);
+ _elm_widget_disabled_eval(obj, disabled);
}
-/* Internal EO API */
-static Eina_Bool
-_elm_widget_item_class_color_set(Eo *obj, Elm_Widget_Item_Data *sd, const char *color_class, int r, int g, int b, int a)
+
+EOLIAN static void
+_efl_ui_widget_show_region_set(Eo *obj, Elm_Widget_Smart_Data *sd, Eina_Rect sr, Eina_Bool forceshow)
{
- ELM_COLOR_CLASS_SET_START(obj, r, g, b, a);
+ Evas_Object *parent_obj, *child_obj;
+ Evas_Coord px, py, cx, cy, nx = 0, ny = 0;
- int_ret &= _elm_widget_item_color_class_update(sd);
+ /*****************************************************************************
+ * TIZEN_ONLY_FEATURE: Fix entry size/cursor/region calculation for Tizen UX *
+ *****************************************************************************
+ * Move this code to the below to update show region geometry properly.
+ evas_smart_objects_calculate(evas_object_evas_get(obj));
+ */
+ /*******
+ * END *
+ *******/
- ELM_COLOR_CLASS_SET_END();
-}
+ if (!forceshow && eina_rectangle_equal(&sr.rect, &sd->show_region.rect)) return;
-/* Internal EO API */
-static Eina_Bool
-_elm_widget_item_class_color_get(const Eo *obj, Elm_Widget_Item_Data *sd, const char *color_class, int *r, int *g, int *b, int *a)
-{
- ELM_COLOR_CLASS_GET(obj, r, g, b, a);
-}
+ sd->show_region = sr;
-/* Internal EO API */
-static Eina_Bool
-_elm_widget_item_class_color2_set(Eo *obj, Elm_Widget_Item_Data *sd, const char *color_class, int r, int g, int b, int a)
-{
- ELM_COLOR_CLASS_SET_START(obj, r2, g2, b2, a2);
+ /*****************************************************************************
+ * TIZEN_ONLY_FEATURE: Fix entry size/cursor/region calculation for Tizen UX *
+ *****************************************************************************/
+ /* Block nested call for evas_smart_objects_calculate() and region showing works */
+ if (sd->on_show_region_set) return;
- int_ret &= _elm_widget_item_color_class_update(sd);
+ sd->on_show_region_set = EINA_TRUE;
- ELM_COLOR_CLASS_SET_END();
-}
+ evas_smart_objects_calculate(evas_object_evas_get(obj));
-/* Internal EO API */
-static Eina_Bool
-_elm_widget_item_class_color2_get(const Eo *obj, Elm_Widget_Item_Data *sd, const char *color_class, int *r, int *g, int *b, int *a)
-{
- ELM_COLOR_CLASS_GET(obj, r2, g2, b2, a2);
-}
+ sd->on_show_region_set = EINA_FALSE;
-/* Internal EO API */
-static Eina_Bool
-_elm_widget_item_class_color3_set(Eo *obj, Elm_Widget_Item_Data *sd, const char *color_class, int r, int g, int b, int a)
-{
- ELM_COLOR_CLASS_SET_START(obj, r3, g3, b3, a3);
+ /* show_region geometry could be changed during processing elm_widget_show_region_set().
+ evas_smart_objects_calculate() can trigger nested show_region_set calls */
+ sr = sd->show_region;
+ /*******
+ * END *
+ *******/
- int_ret &= _elm_widget_item_color_class_update(sd);
+ if (sd->on_show_region)
+ {
+ sd->on_show_region(sd->on_show_region_data, obj, sr);
- ELM_COLOR_CLASS_SET_END();
+ if (_elm_scrollable_is(obj))
+ {
+ if (elm_widget_is_legacy(obj))
+ {
+ elm_interface_scrollable_content_pos_get(obj, &nx, &ny);
+ sr.x -= nx;
+ sr.y -= ny;
+ }
+ else
+ {
+ Eina_Position2D pos;
+ pos = efl_ui_scrollable_content_pos_get(obj);
+ sr.x -= pos.x;
+ sr.y -= pos.y;
+ }
+ }
+ }
+
+ do
+ {
+ parent_obj = sd->parent_obj;
+ child_obj = sd->obj;
+ if ((!parent_obj) || (!_elm_widget_is(parent_obj))) break;
+ sd = efl_data_scope_get(parent_obj, MY_CLASS);
+ if (!sd) break;
+
+ evas_object_geometry_get(parent_obj, &px, &py, NULL, NULL);
+ evas_object_geometry_get(child_obj, &cx, &cy, NULL, NULL);
+
+ sr.x += (cx - px);
+ sr.y += (cy - py);
+ sd->show_region = sr;
+
+ if (sd->on_show_region)
+ sd->on_show_region(sd->on_show_region_data, parent_obj, sr);
+ }
+ while (parent_obj);
}
-/* Internal EO API */
-static Eina_Bool
-_elm_widget_item_class_color3_get(const Eo *obj, Elm_Widget_Item_Data *sd, const char *color_class, int *r, int *g, int *b, int *a)
+EOLIAN static Eina_Rect
+_efl_ui_widget_show_region_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
{
- ELM_COLOR_CLASS_GET(obj, r3, g3, b3, a3);
+ return (Eina_Rect) sd->show_region;
}
-/* Internal EO API */
-static Evas_Object *
-_elm_widget_item_edje_get(const Eo *obj, Elm_Widget_Item_Data *sd)
+//TIZEN_ONLY(20180607): Restore legacy focus
+/**
+ * @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)
{
- if (!sd)
- sd = efl_data_scope_get(obj, ELM_WIDGET_ITEM_CLASS);
+ ELM_WIDGET_CHECK(obj) EINA_FALSE;
- if (efl_isa(sd->view, EFL_UI_LAYOUT_CLASS))
- return elm_layout_edje_get(sd->view);
- else if (efl_isa(sd->view, EFL_CANVAS_LAYOUT_CLASS))
- return sd->view;
+ Eina_Bool manager_is = EINA_FALSE;
+ manager_is = efl_ui_widget_focus_next_manager_is((Eo *)obj);
+ return manager_is;
+}
- return NULL;
+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 = efl_ui_widget_focus_direction_manager_is((Eo *)obj);
+ return manager_is;
}
-/* Internal EO API */
static void
-_elm_widget_item_class_color_del(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *sd, const char *color_class)
+_parent_focus(Evas_Object *obj, Elm_Object_Item *item)
{
- Eina_Stringshare *buf;
- Evas_Object *edje;
- Edje_Color_Class *cc = NULL;
+ API_ENTRY return;
- if (!color_class) return;
+ if (sd->focused) return;
- buf = _elm_widget_edje_class_get(obj, NULL, color_class);
- eina_hash_del(sd->color_classes, buf, cc);
+ Evas_Object *o = elm_widget_parent_get(obj);
+ sd->focus_order_on_calc = EINA_TRUE;
- edje = _elm_widget_item_edje_get(obj, sd);
- if (edje)
- edje_object_color_class_del(edje, buf);
+ if (o) _parent_focus(o, item);
- eina_stringshare_del(buf);
-}
+ 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. */
-/* Internal EO API */
-static void
-_elm_widget_item_class_color_clear(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *sd)
-{
- Evas_Object *edje;
- ELM_SAFE_FREE(sd->color_classes, eina_hash_free);
+ focus_order++;
+ sd->focus_order = focus_order;
+ sd->focused = EINA_TRUE;
- edje = _elm_widget_item_edje_get(obj, sd);
- if (!edje) return;
+ if (sd->top_win_focused)
+ efl_ui_focus_object_on_focus_update(obj);
+ sd->focus_order_on_calc = EINA_FALSE;
- edje_object_color_class_clear(edje);
+ if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
+ _elm_access_highlight_set(obj);
}
-/* Internal EO APIs and hidden overrides */
-EAPI EFL_FUNC_BODYV(elm_widget_item_class_color_set, Eina_Bool, EINA_FALSE,
- EFL_FUNC_CALL(color_class, r, g, b, a),
- const char *color_class, int r, int g, int b, int a)
-EAPI EFL_FUNC_BODYV(elm_widget_item_class_color_get, Eina_Bool, EINA_FALSE,
- EFL_FUNC_CALL(color_class, r, g, b, a),
- const char *color_class, int *r, int *g, int *b, int *a)
-EAPI EFL_FUNC_BODYV(elm_widget_item_class_color2_set, Eina_Bool, EINA_FALSE,
- EFL_FUNC_CALL(color_class, r, g, b, a),
- const char *color_class, int r, int g, int b, int a)
-EAPI EFL_FUNC_BODYV(elm_widget_item_class_color2_get, Eina_Bool, EINA_FALSE,
- EFL_FUNC_CALL(color_class, r, g, b, a),
- const char *color_class, int *r, int *g, int *b, int *a)
-EAPI EFL_FUNC_BODYV(elm_widget_item_class_color3_set, Eina_Bool, EINA_FALSE,
- EFL_FUNC_CALL(color_class, r, g, b, a),
- const char *color_class, int r, int g, int b, int a)
-EAPI EFL_FUNC_BODYV(elm_widget_item_class_color3_get, Eina_Bool, EINA_FALSE,
- EFL_FUNC_CALL(color_class, r, g, b, a),
- const char *color_class, int *r, int *g, int *b, int *a)
-EAPI EFL_VOID_FUNC_BODYV(elm_widget_item_class_color_del,
- EFL_FUNC_CALL(color_class),
- const char *color_class)
-EAPI EFL_VOID_FUNC_BODY(elm_widget_item_class_color_clear)
-
-#define ELM_WIDGET_ITEM_EXTRA_OPS \
- EFL_OBJECT_OP_FUNC(elm_widget_item_class_color_set, _elm_widget_item_class_color_set), \
- EFL_OBJECT_OP_FUNC(elm_widget_item_class_color_get, _elm_widget_item_class_color_get), \
- EFL_OBJECT_OP_FUNC(elm_widget_item_class_color2_set, _elm_widget_item_class_color2_set), \
- EFL_OBJECT_OP_FUNC(elm_widget_item_class_color2_get, _elm_widget_item_class_color2_get), \
- EFL_OBJECT_OP_FUNC(elm_widget_item_class_color3_set, _elm_widget_item_class_color3_set), \
- EFL_OBJECT_OP_FUNC(elm_widget_item_class_color3_get, _elm_widget_item_class_color3_get), \
- EFL_OBJECT_OP_FUNC(elm_widget_item_class_color_del, _elm_widget_item_class_color_del), \
- EFL_OBJECT_OP_FUNC(elm_widget_item_class_color_clear, _elm_widget_item_class_color_clear)
-
-/*******
- * END *
- *******/
+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);
+}
+//
#include "elm_widget_item.eo.c"
#include "efl_ui_widget.eo.c"