2 * Copyright (c) 2013 Samsung Electronics Co., Ltd.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this library; see the file COPYING.LIB. If not, write to
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
22 * @brief EailWidget implementation
26 #include <Ecore_Evas.h>
27 #include <Elementary.h>
29 #include "eail_widget.h"
30 #include "eail_factory.h"
31 #include "eail_utils.h"
32 #include "eail_priv.h"
34 static void atk_component_interface_init(AtkComponentIface *iface);
37 * @brief EailWidget type definition
39 G_DEFINE_TYPE_WITH_CODE(EailWidget, eail_widget, ATK_TYPE_OBJECT,
40 G_IMPLEMENT_INTERFACE(ATK_TYPE_COMPONENT,
41 atk_component_interface_init));
44 * @brief Gets Evas_Object from EailWidget
46 * @param widget EailWidget instance
47 * @return Evas_Object widget representing the EailWidget
50 eail_widget_get_widget(EailWidget *widget)
52 g_return_val_if_fail(EAIL_IS_WIDGET(widget), NULL);
54 return widget->widget;
58 * @brief Gets EailWidget's children
60 * @param widget EailWidget instance
61 * @return Eina_List representing the EailWidget's children list
64 eail_widget_get_widget_children(EailWidget *widget)
66 EailWidgetClass *klass;
68 g_return_val_if_fail(EAIL_IS_WIDGET(widget), NULL);
70 klass = EAIL_WIDGET_GET_CLASS(widget);
71 return klass->get_widget_children(widget);
75 * @brief Callback used for tracking focus-in changes for widgets
77 * @param data data passed to callback
78 * @param e Evas instance that has been focused in
79 * @param obj Evas_Object instance that has been focused in
80 * @param event_info additional event info
83 eail_widget_on_focused_in(void *data, Evas *e, Evas_Object *obj, void *event_info)
85 g_return_if_fail(ATK_IS_OBJECT(data));
87 atk_object_notify_state_change(ATK_OBJECT(data), ATK_STATE_FOCUSED, TRUE);
88 atk_focus_tracker_notify(ATK_OBJECT(data));
92 * @brief Callback used for tracking show-changes for widgets
94 * @param data data passed to callback
95 * @param e Evas instance that has been shown
96 * @param obj Evas_Object instance that has been shown
97 * @param event_info additional event info
100 eail_widget_on_show(void *data, Evas *e, Evas_Object *obj, void *event_info)
102 g_return_if_fail(ATK_IS_OBJECT(data));
104 atk_object_notify_state_change(ATK_OBJECT(data), ATK_STATE_SHOWING, TRUE);
108 * @brief Callback used for tracking hide-changes for widgets
110 * @param data data passed to callback
111 * @param e Evas instance that has been shown
112 * @param obj Evas_Object instance that has been shown
113 * @param event_info additional event info
116 eail_widget_on_hide(void *data, Evas *e, Evas_Object *obj, void *event_info)
118 g_return_if_fail(ATK_IS_OBJECT(data));
120 atk_object_notify_state_change(ATK_OBJECT(data), ATK_STATE_SHOWING, FALSE);
124 * @brief Callback used for tracking focus-out changes for widgets
126 * @param data data passed to callback
127 * @param e Evas instance that has been focused out
128 * @param obj Evas_Object instance that has been focused out
129 * @param event_info additional event info
132 eail_widget_on_focused_out(void *data, Evas *e, Evas_Object *obj, void *event_info)
134 g_return_if_fail(ATK_IS_OBJECT(data));
137 atk_object_notify_state_change(ATK_OBJECT(data), ATK_STATE_FOCUSED, FALSE);
138 atk_focus_tracker_notify(ATK_OBJECT(data));
139 eail_notify_child_focus_changes();
143 * @brief Callback used to tracking bounds-change changes for widgets
145 * @param data data passed to callback
146 * @param e an Evas that has been focused out
147 * @param obj an Evas_Object that has been focused out
148 * @param event_info additional event info
151 eail_widget_on_bounds_change(void *data, Evas *e, Evas_Object *obj, void *event_info)
153 g_return_if_fail(ATK_IS_COMPONENT(data));
156 evas_object_geometry_get(obj, &rect.x, &rect.y, &rect.width, &rect.height);
157 g_signal_emit_by_name (ATK_OBJECT(data), "bounds_changed", &rect);
162 * @brief Default callback for on_focused used for tracking focus changes of
165 * @param data data passed to callback
166 * @param obj Evas_Object instance that has been shown
167 * @param event_info additional event info
169 void eail_widget_on_focused_smart(void *data,
173 g_return_if_fail(ATK_IS_OBJECT(data));
176 atk_object_notify_state_change(ATK_OBJECT(data), ATK_STATE_FOCUSED, TRUE);
177 atk_focus_tracker_notify(ATK_OBJECT(data));
178 eail_notify_child_focus_changes();
182 * @brief on_focused default callback used to tracking focus changes of
185 * @param data data passed to callback
186 * @param obj an Evas_Object that has been shown
187 * @param event_info additional event info
189 void eail_widget_on_focused_out_smart(void *data,
193 g_return_if_fail(ATK_IS_OBJECT(data));
196 /* Not propagating further, using only for internal eail focus changes*/
197 eail_notify_child_focus_changes();
201 * @brief EailWidget initializer
203 * @param obj AtkObject instance
204 * @param data initialization data
207 eail_widget_initialize(AtkObject *obj, gpointer data)
209 EailWidget *widget = EAIL_WIDGET(obj);
211 ATK_OBJECT_CLASS(eail_widget_parent_class)->initialize(obj, data);
213 widget->widget = (Evas_Object *)data;
214 widget->layer = ATK_LAYER_WIDGET;
216 obj->name = g_strdup(evas_object_name_get(widget->widget));
217 obj->role = ATK_ROLE_UNKNOWN;
219 if (!widget->widget) {
220 ERR("No evas object inside EailWidget was found");
224 evas_object_event_callback_add(widget->widget, EVAS_CALLBACK_FOCUS_IN,
225 eail_widget_on_focused_in, widget);
226 evas_object_event_callback_add(widget->widget, EVAS_CALLBACK_FOCUS_OUT,
227 eail_widget_on_focused_out, widget);
229 evas_object_event_callback_add(widget->widget, EVAS_CALLBACK_SHOW,
230 eail_widget_on_show, widget);
231 evas_object_event_callback_add(widget->widget, EVAS_CALLBACK_HIDE,
232 eail_widget_on_hide, widget);
234 evas_object_event_callback_add(widget->widget, EVAS_CALLBACK_RESIZE,
235 eail_widget_on_bounds_change, widget);
236 evas_object_event_callback_add(widget->widget, EVAS_CALLBACK_MOVE,
237 eail_widget_on_bounds_change, widget);
238 /* for window don't need that event, it would result double generating
240 if (!ATK_IS_WINDOW(obj))
241 evas_object_smart_callback_add
242 (widget->widget, "focused", eail_widget_on_focused_smart, widget);
244 evas_object_smart_callback_add
245 (widget->widget, "unfocused", eail_widget_on_focused_out_smart, widget);
250 * @brief Default get_widget_children callback
252 * @param widget EailWidget instance
256 eail_widget_get_real_widget_children(EailWidget *widget)
262 * @brief Gets the number of children of obj
264 * @param obj AtkObject instance
266 * @returns integer representing the number of widget's children
269 eail_widget_get_n_children(AtkObject *obj)
274 children = eail_widget_get_widget_children(EAIL_WIDGET(obj));
275 n_children = eina_list_count(children);
277 eina_list_free(children);
283 * @brief Gets reference to specified child of obj
285 * The caller must unreference it when it is no longer needed.
287 * @param obj AtkObject instance
288 * @param i child index
289 * @return AtkObject representing the specified child of obj
292 eail_widget_ref_child(AtkObject *obj, gint i)
295 AtkObject *child = NULL;
297 children = eail_widget_get_widget_children(EAIL_WIDGET(obj));
298 if (eina_list_count(children) > i) {
299 child = eail_factory_get_accessible(eina_list_nth(children, i));
303 eina_list_free(children);
309 * @brief Gets the parent of obj
311 * @param obj AtkObject instance
312 * @return AtkObject representing the parent of obj
315 eail_widget_get_parent(AtkObject *obj)
317 Evas_Object *widget = eail_widget_get_widget(EAIL_WIDGET(obj));
323 if (obj->accessible_parent) {
324 return obj->accessible_parent;
327 return eail_factory_get_accessible(elm_object_parent_widget_get(widget));
331 * @brief Gets the 0-based index of this accessible in its parent
333 * Returns -1 if the accessible does not have an accessible parent.
335 * @param obj AtkObject instance
336 * @return integer representing obj's index in its parent
339 eail_widget_get_index_in_parent(AtkObject *obj)
342 Eina_List *l, *children;
345 Evas_Object *widget = eail_widget_get_widget(EAIL_WIDGET(obj));
351 if (obj->accessible_parent)
353 parent = obj->accessible_parent;
355 parent = atk_object_get_parent(obj);
363 children = eail_widget_get_widget_children(EAIL_WIDGET(parent));
364 EINA_LIST_FOREACH(children, l, child) {
366 if (child == widget) {
371 eina_list_free(children);
377 * @brief Gets the state set of obj
379 * @param obj AtkObject instance
380 * @return AtkState representing the state set of obj
383 eail_widget_ref_state_set(AtkObject *obj)
385 AtkStateSet *state_set;
386 Evas_Object *widget = eail_widget_get_widget(EAIL_WIDGET(obj));
388 state_set= ATK_OBJECT_CLASS(eail_widget_parent_class)->ref_state_set(obj);
390 return eail_evas_obj_ref_state_set(widget, state_set);
394 * @brief Gets the attribute set of obj
396 * @param obj AtkObject instance
397 * @return AtkAttributeSet representing obj's attribute set
399 static AtkAttributeSet *
400 eail_widget_get_attributes(AtkObject *obj)
403 AtkAttributeSet *attributes;
404 Evas_Object *widget = eail_widget_get_widget(EAIL_WIDGET(obj));
410 attr = g_new(AtkAttribute, 1);
411 attr->name = g_strdup("type");
412 attr->value = g_strdup(elm_object_widget_type_get(widget));
414 attributes = g_slist_append(NULL, attr);
420 * @brief EailWidget instance initializer
422 * @param widget EailWidget instance
425 eail_widget_init(EailWidget *widget)
430 * @brief EailWidget finalizer
432 * Frees memory assigned to object.
434 * @param obj GObject instance
437 eail_widget_class_finalize(GObject *obj)
439 EailWidget *eail_widget = EAIL_WIDGET(obj);
440 Evas_Object *evas_widget = eail_widget_get_widget(eail_widget);
443 eail_factory_unregister_wdgt_from_cache(evas_widget);
445 G_OBJECT_CLASS(eail_widget_parent_class)->finalize(obj);
449 * @brief EailWidget class initializer
451 * Function called upon instance creation. It initializes AtkObject class
452 * callbacks for EailWidget.
454 * @param klass EailWidgetClass instance
457 eail_widget_class_init(EailWidgetClass *klass)
459 AtkObjectClass *atk_class = ATK_OBJECT_CLASS(klass);
460 GObjectClass *g_object_class = G_OBJECT_CLASS(klass);
462 klass->get_widget_children = eail_widget_get_real_widget_children;
464 atk_class->initialize = eail_widget_initialize;
465 atk_class->get_n_children = eail_widget_get_n_children;
466 atk_class->ref_child = eail_widget_ref_child;
467 atk_class->get_parent = eail_widget_get_parent;
468 atk_class->get_index_in_parent = eail_widget_get_index_in_parent;
469 atk_class->ref_state_set = eail_widget_ref_state_set;
470 atk_class->get_attributes = eail_widget_get_attributes;
472 g_object_class->finalize = eail_widget_class_finalize;
476 * @brief Grabs focus of a component
478 * @param component AtkComponent instance
479 * @return TRUE on success, FALSE otherwise
482 eail_widget_grab_focus(AtkComponent *component)
484 Evas_Object *widget = eail_widget_get_widget(EAIL_WIDGET(component));
486 return eail_evas_obj_grab_focus(widget);
490 * @brief Gets component's layer
492 * @param component AtkComponent instance
493 * @return AtkLayer representing the component's layer
496 eail_widget_get_layer(AtkComponent *component)
498 return EAIL_WIDGET(component)->layer;
502 * @brief Gets the rectangle which gives the extent of the component
504 * @param component AtkComponent instance
505 * @param [out] x upper left x coordinate of the rectangle
506 * @param [out] y upper left y coordinate of the rectangle
507 * @param [out] width width of the rectangle
508 * @param [out] height height of the rectangle
509 * @param coord_type coordinates type
512 eail_widget_get_extents(AtkComponent *component,
517 AtkCoordType coord_type)
519 Evas_Object *widget = eail_widget_get_widget(EAIL_WIDGET(component));
522 *width = *height = -1;
527 evas_object_geometry_get(widget, x, y, width, height);
529 if (coord_type == ATK_XY_SCREEN) {
531 Ecore_Evas *ee= ecore_evas_ecore_evas_get(evas_object_evas_get(widget));
533 ecore_evas_geometry_get(ee, &ee_x, &ee_y, NULL, NULL);
540 * @brief Sets component position
542 * @param component AtkComponent instance
543 * @param x upper left x coordinate
544 * @param y upper left y coordinate
545 * @param coord_type coordinates type
546 * @return TRUE on success, FALSE otherwise
549 eail_widget_set_position(AtkComponent *component,
552 AtkCoordType coord_type)
554 Evas_Object *widget = eail_widget_get_widget(EAIL_WIDGET(component));
556 if (!widget) return FALSE;
558 if (x < 0 || y < 0) return FALSE;
560 if (coord_type == ATK_XY_SCREEN) {
562 Ecore_Evas *ee= ecore_evas_ecore_evas_get(evas_object_evas_get(widget));
564 ecore_evas_geometry_get(ee, &ee_x, &ee_y, NULL, NULL);
569 evas_object_move(widget, x, y);
575 * @brief Sets component size
577 * @param component AtkComponent instance
578 * @param width new width of component
579 * @param height new height of component
580 * @return TRUE on success, FALSE otherwise
583 eail_widget_set_size(AtkComponent *component,
587 Evas_Object *widget = eail_widget_get_widget(EAIL_WIDGET(component));
589 if (!widget) return FALSE;
591 if (width <= 0 || height <= 0) return FALSE;
593 evas_object_resize(widget, width, height);
599 * @brief Sets component extents
601 * @param component AtkComponent instance
602 * @param x new upper left x coordinate
603 * @param y new upper left y coordinate
604 * @param width new width of component
605 * @param height new height of component
606 * @param coord_type coordinates type
607 * @return TRUE on success, FALSE otherwise
610 eail_widget_set_extents(AtkComponent *component,
615 AtkCoordType coord_type)
617 Evas_Object *widget = eail_widget_get_widget(EAIL_WIDGET(component));
623 if (coord_type == ATK_XY_SCREEN) {
625 Ecore_Evas *ee= ecore_evas_ecore_evas_get(evas_object_evas_get(widget));
627 ecore_evas_geometry_get(ee, &ee_x, &ee_y, NULL, NULL);
632 if (x < 0 || y < 0) {
636 evas_object_move(widget, x, y);
637 evas_object_resize(widget, width, height);
643 * @brief Sets function to execute whenever component gets focus
645 * @param component AtkComponent instance
646 * @param handler AtkFocusHandler instance
647 * @returns integer representing the handler's id
650 eail_widget_add_focus_handler(AtkComponent *component,
651 AtkFocusHandler handler)
653 GSignalMatchType match_type;
657 match_type = G_SIGNAL_MATCH_ID;
658 signal_id = g_signal_lookup("focus-event", ATK_TYPE_OBJECT);
660 ret = g_signal_handler_find(component, match_type, signal_id, 0, NULL,
661 (gpointer)handler, NULL);
664 return g_signal_connect_closure_by_id(component,
667 G_CALLBACK(handler), NULL,
668 (GClosureNotify)NULL),
678 * @brief Gets alpha value
680 * @param component an AtkComponent
681 * @return alpha value
684 eail_widget_get_alpha(AtkComponent *component)
686 Evas_Object *widget = eail_widget_get_widget(EAIL_WIDGET(component));
689 evas_object_color_get(widget, NULL, NULL, NULL, &alpha);
691 return (gdouble)alpha/255.0;
695 * @brief AtkComponent interface initialization
697 * @param iface EailNaviframPage instance
700 atk_component_interface_init(AtkComponentIface *iface)
702 iface->grab_focus = eail_widget_grab_focus;
703 iface->get_layer = eail_widget_get_layer;
704 iface->get_extents = eail_widget_get_extents;
705 iface->set_position = eail_widget_set_position;
706 iface->set_size = eail_widget_set_size;
707 iface->set_extents = eail_widget_set_extents;
708 iface->add_focus_handler = eail_widget_add_focus_handler;
709 iface->get_alpha = eail_widget_get_alpha;