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 EailList implementation
25 #include <Elementary.h>
27 #include "eail_list.h"
28 #include "eail_item_parent.h"
29 #include "eail_factory.h"
30 #include "eail_utils.h"
31 #include "eail_priv.h"
33 static void eail_item_parent_interface_init(EailItemParentIface *iface);
34 static void atk_selection_interface_init(AtkSelectionIface *iface);
37 * @brief Definition of EailList as GObject
39 * EailList is extended ScrollableWidget with EAIL_TYPE_ITEM_PARENT and
40 * ATK_TYPE_SELECTION implemented
42 G_DEFINE_TYPE_WITH_CODE(EailList,
44 EAIL_TYPE_SCROLLABLE_WIDGET,
45 G_IMPLEMENT_INTERFACE(EAIL_TYPE_ITEM_PARENT,
46 eail_item_parent_interface_init)
47 G_IMPLEMENT_INTERFACE(ATK_TYPE_SELECTION,
48 atk_selection_interface_init));
51 * @brief Initializer for AtkObjectClass
53 * @param obj AtkObject instance
54 * @param data initialization data
57 eail_list_initialize(AtkObject *obj, gpointer data)
59 Evas_Object *nested_widget = NULL;
60 ATK_OBJECT_CLASS(eail_list_parent_class)->initialize(obj, data);
62 obj->role = ATK_ROLE_LIST;
64 g_return_if_fail(EAIL_IS_WIDGET(obj));
65 nested_widget = eail_widget_get_widget(EAIL_WIDGET(obj));
68 ERR("No evas object inside EailWidget was found");
72 evas_object_smart_callback_add(nested_widget, "selected",
73 eail_list_item_handle_selected_event, obj);
74 evas_object_smart_callback_add(nested_widget, "unselected",
75 eail_list_item_handle_unselected_event, obj);
79 * @brief Prepares Eina_List filled with Elm_Object_Item* objects
80 * representing items in the list
82 * Call eina_list_free on the returned when results processing has been finished.
84 * @param list EailList instance
86 * @return Eina_List representing a list of the list's item
89 eail_list_get_items(EailList *list)
91 Eina_List *items = NULL;
92 Elm_Object_Item *item;
93 Evas_Object *widget = eail_widget_get_widget(EAIL_WIDGET(list));
95 item = elm_list_first_item_get(widget);
98 items = eina_list_append(items, item);
99 item = elm_list_item_next(item);
106 * @brief Gets the number of accessible children of the accessible
108 * Implementation of AtkObject->get_n_children callback.
110 * @param obj AtkObject instance
112 * @returns integer representing the number of accessible children of
116 eail_list_get_n_children(AtkObject *obj)
121 items = eail_list_get_items(EAIL_LIST(obj));
122 n_items = eina_list_count(items);
124 eina_list_free(items);
130 * @brief Gets a reference to the specified accessible child of the object.
132 * The accessible children are 0-based so the first accessible child is at index 0,
133 * the second at index 1 and so on.
135 * Implementation of AtkObject->ref_child callback.
137 * @param obj AtkObject instance
138 * @param i child index
140 * @returns AtkObject representing the specified accessible child of the
144 eail_list_ref_child(AtkObject *obj, gint i)
147 AtkObject *child = NULL;
149 items = eail_list_get_items(EAIL_LIST(obj));
150 if (eina_list_count(items) > i)
152 if (elm_list_item_separator_get(eina_list_nth(items, i)))
153 child = eail_factory_get_item_atk_obj
154 (eina_list_nth(items, i), ATK_ROLE_SEPARATOR, obj);
156 child = eail_factory_get_item_atk_obj
157 (eina_list_nth(items, i), ATK_ROLE_LIST_ITEM, obj);
162 eina_list_free(items);
168 * @brief Gets a reference to the state set of the accessible
170 * The caller must unreference it when it is no longer needed.
172 * Implementation of AtkObject->ref_state_set callback.
174 * @param obj AtkObject instance
176 * @returns AtkStateSet representing the state set of the
180 eail_list_ref_state_set(AtkObject *obj)
182 AtkStateSet *state_set;
183 Evas_Object *widget = eail_widget_get_widget(EAIL_WIDGET(obj));
185 state_set = ATK_OBJECT_CLASS(eail_list_parent_class)->ref_state_set(obj);
187 if (!widget) return state_set;
189 if (elm_list_multi_select_get(widget))
190 atk_state_set_add_state(state_set, ATK_STATE_MULTISELECTABLE);
196 * @brief Initializer for GObject EailList instance
198 * @param list EailList instance
201 eail_list_init(EailList *list)
206 * @brief Initializer for GObject class
208 * Defines callbacks for base AtkObject.
210 * @param klass EailListClass instance
213 eail_list_class_init(EailListClass *klass)
215 AtkObjectClass *atk_class = ATK_OBJECT_CLASS(klass);
217 atk_class->initialize = eail_list_initialize;
218 atk_class->get_n_children = eail_list_get_n_children;
219 atk_class->ref_child = eail_list_ref_child;
220 atk_class->ref_state_set = eail_list_ref_state_set;
224 * Functions for *EailItemParent* interface
228 * @brief Gets the role of item
230 * Implementation of EailItemParent->get_item_role callback.
232 * @param parent EailItemParent instance
233 * @param item EailItem instance
235 * @returns AtkRole representing the role of the specified item in the list
238 eail_list_get_item_role(EailItemParent *parent,
241 Evas_Object *widget = eail_widget_get_widget(EAIL_WIDGET(parent));
242 Elm_Object_Item *it = eail_item_get_item(item);
244 if (!widget || !it) return ATK_ROLE_INVALID;
246 return ATK_OBJECT(item)->role;
250 * @brief Gets a reference to the state set of item
252 * Implementation of EailItemParent->ref_item_state_set callback.
254 * @param parent EailItemParent instance
255 * @param item EailItem instance
256 * @param state_set AtkStateSet instance
257 * @returns AtkStateSet representing the state set of item
260 eail_list_ref_item_state_set(EailItemParent *parent,
262 AtkStateSet *state_set)
264 Evas_Object *widget = eail_widget_get_widget(EAIL_WIDGET(parent));
265 Elm_Object_Item *it = eail_item_get_item(item);
267 if (!widget || !it) return state_set;
269 if (elm_list_select_mode_get(widget) != ELM_OBJECT_SELECT_MODE_NONE)
271 atk_state_set_add_state(state_set, ATK_STATE_SELECTABLE);
273 if (elm_list_item_selected_get(it))
274 atk_state_set_add_state(state_set, ATK_STATE_SELECTED);
277 atk_state_set_add_state(state_set, ATK_STATE_VISIBLE);
278 atk_state_set_add_state(state_set, ATK_STATE_SHOWING);
284 * @brief Grabs focus of list
286 * @param parent EailItemParent instance
287 * @param item EailItem instance
288 * @returns TRUE on success, FALSE otherwise
291 eail_list_grab_item_focus(EailItemParent *parent,
294 /* it is not possible to focus entire list object */
299 * @brief Gets nested Evas_Object of given EailItem
301 * Implementation of EailItemParent->get_evas_obj callback.
303 * @param parent EailItemParent instance
304 * @param item EailItem instance
305 * @returns Evas_Object representing item
308 eail_list_get_evas_obj(EailItemParent *parent,
311 Elm_Object_Item *it = eail_item_get_item(item);
315 ERR("Error. Could not get Elm_Object_item from EailItem");
319 return elm_list_item_object_get(it);
323 * @brief Gets supported actions
325 * Implementation of EailItemParent->get_actions_supported callback.
327 * @param parent EailItemParent instance
328 * @param item EailItem instance
329 * @returns integer representing supported actions
332 eail_list_get_actions_supported(EailItemParent *parent,
335 return EAIL_ACTION_SUPPORTED_CLICK;
339 * @brief Gets index in parent
341 * @param parent EailItemParent instance
342 * @param item EailItem child instance
344 * @returns int representing the index in parent
347 eail_list_get_item_index_in_parent(EailItemParent *parent, EailItem *item)
349 Elm_Object_Item *it = eail_item_get_item(item);
356 items = eail_list_get_items(EAIL_LIST(ATK_OBJECT(parent)));
357 for (i=0; i<eina_list_count(items); ++i)
359 if (eina_list_nth(items, i) == it)
366 eina_list_free(items);
371 * @brief Gets the name of a list's child
373 * @param parent EailItemParent instance
374 * @param item EailItem child instance
376 * @returns string representing the name of the child
379 eail_list_item_name_get(EailItemParent *parent, EailItem *item)
381 Elm_Object_Item *it = eail_item_get_item(item);
382 /*that will work only for default theme*/
383 if (!it) return NULL;
385 return elm_object_item_part_text_get(it, NULL);
389 * @brief Initialization of EailItemParentIface callbacks
391 * @param iface EailItemParent instance
394 eail_item_parent_interface_init(EailItemParentIface *iface)
396 iface->get_item_name = eail_list_item_name_get;
397 iface->get_item_role = eail_list_get_item_role;
398 iface->ref_item_state_set = eail_list_ref_item_state_set;
399 iface->grab_item_focus = eail_list_grab_item_focus;
400 iface->get_evas_obj = eail_list_get_evas_obj;
401 iface->get_actions_supported = eail_list_get_actions_supported;
402 iface->get_item_index_in_parent = eail_list_get_item_index_in_parent;
406 * Functions for the *AtkSelection* interface
410 * @brief Adds the specified accessible child of the object to the object's selection
412 * Implementation of AtkSelection->add_selection callback.
414 * @param selection AtkSelection instance
415 * @param i index of object
417 * @returns TRUE on success, FALSE otherwise
420 eail_list_add_selection(AtkSelection *selection,
423 g_return_val_if_fail(EAIL_IS_WIDGET(selection), FALSE);
424 Evas_Object *object = eail_widget_get_widget(EAIL_WIDGET(selection));
425 const Eina_List *items = elm_list_items_get(object);
426 Elm_Object_Item *item = eina_list_nth(items, i);
428 if (!item) return FALSE;
430 elm_list_item_selected_set(item, EINA_TRUE);
435 * @brief Gets a reference to the accessible object representing the specified selected
436 * child of the object.
438 * Note: callers should not rely on NULL or on a zero value
439 * for indication of whether AtkSelectionIface is implemented, they should use
440 * type checking/interface checking macros or the atk_get_accessible_value()
441 * convenience method.
443 * Implementation of AtkSelection->ref_selection callback.
445 * @param selection AtkSelection instance
446 * @param i index of object
448 * @returns AtkObject representing the selected accessible
451 eail_list_ref_selection(AtkSelection *selection,
454 g_return_val_if_fail(EAIL_IS_WIDGET(selection), NULL);
456 return eail_list_ref_child(ATK_OBJECT(selection), i);
460 * @brief Gets the number of accessible children currently selected.
462 * Note: callers should not rely on NULL or on a zero value for indication of whether
463 * AtkSelectionIface is implemented, they should use type checking/interface
464 * checking macros or the atk_get_accessible_value() convenience method.
466 * Implementation of AtkSelection->get_selection_count callback.
468 * @param selection AtkSelection instance
470 * @returns integer representing the number of selected elements
473 eail_list_get_selection_count(AtkSelection *selection)
475 g_return_val_if_fail(EAIL_IS_WIDGET(selection), FALSE);
476 Evas_Object *object = eail_widget_get_widget(EAIL_WIDGET(selection));
477 const Eina_List *sel_objs = elm_list_selected_items_get(object);
479 if (!sel_objs) return 0;
481 return eina_list_count(sel_objs);
485 * @brief Determines if the current child of this object is selected.
487 * Note: callers should not rely on NULL or on a zero value for indication of whether
488 * AtkSelectionIface is implemented, they should use type checking/interface
489 * checking macros or the atk_get_accessible_value() convenience method.
491 * Implementation of AtkSelection->is_child_selected callback.
493 * @param selection AtkSelection instance
494 * @param i index of object
496 * @returns gboolean representing whether the specified child is selected
499 eail_list_is_child_selected(AtkSelection *selection,
502 g_return_val_if_fail(EAIL_IS_WIDGET(selection), FALSE);
503 Evas_Object *object = eail_widget_get_widget(EAIL_WIDGET(selection));
504 Elm_Object_Item *selected_item = elm_list_selected_item_get(object);
505 Elm_Object_Item *last_item = elm_list_last_item_get(object);
506 Elm_Object_Item *item = elm_list_first_item_get(object);
509 /* if there is no selected object, that naturally means that none
510 * of children is selected */
511 if (!selected_item) return FALSE;
515 if (selected_item == item) break;
517 item = elm_list_item_next(item);
519 } while (item != last_item);
525 * @brief Removes the specified child of the object from the object's selection
527 * Implementation of AtkSelection->remove_selection callback.
529 * @param selection AtkSelection instance
530 * @param i selection index
532 * @returns TRUE on success, FALSE otherwise
535 eail_list_remove_selection(AtkSelection *selection,
538 const Eina_List *items = NULL;
539 Evas_Object *object = NULL;
540 Elm_Object_Item *item = NULL;
542 g_return_val_if_fail(EAIL_IS_WIDGET(selection), FALSE);
543 object = eail_widget_get_widget(EAIL_WIDGET(selection));
544 g_return_val_if_fail(object, FALSE);
546 items = elm_list_items_get(object);
547 g_return_val_if_fail((eina_list_count(items) > i), FALSE);
549 item = eina_list_nth(items, i);
550 elm_list_item_selected_set(item, EINA_FALSE);
552 /* if change was successful, then selected item now should be different */
553 return (elm_list_selected_item_get(object) != item);
557 * @brief Helper function that selects/unselects all items in the list depending
558 * on "selected" param value
560 * @param object Evas_Object instance
561 * @param selected selected state (TRUE means selected)
563 * @returns TRUE on success, FALSE otherwise
566 eail_list_mark_all_selected_state(const Evas_Object *object, Eina_Bool selected)
568 const Eina_List *items = NULL;
571 items = elm_list_items_get(object);
572 for (i = 0; i < eina_list_count(items); ++i)
574 Elm_Object_Item *item = eina_list_nth(items, i);
575 if (!item) return FALSE;
577 elm_list_item_selected_set(item, selected);
584 * @brief Causes every child of the object to be selected if the object supports
585 * multiple selections
587 * Implementation of AtkSelection->select_all_selection callback.
589 * @param selection AtkSelection instance
591 * @returns TRUE on success, FALSE otherwise
594 eail_list_select_all_selection(AtkSelection *selection)
596 g_return_val_if_fail(EAIL_IS_WIDGET(selection), FALSE);
597 Evas_Object *object = eail_widget_get_widget(EAIL_WIDGET(selection));
599 /* can select all only when multiselect is enabled */
600 if (!elm_list_multi_select_get(object)) return FALSE;
602 return eail_list_mark_all_selected_state(object, EINA_TRUE);
606 * @brief Clears the selection in the object so that no child in the object is
609 * Implementation of AtkSelection->clear_selection callback.
611 * @param selection AtkSelection instance
613 * @returns TRUE on success, FALSE otherwise
616 eail_list_clear_selection(AtkSelection *selection)
618 g_return_val_if_fail(EAIL_IS_WIDGET(selection), FALSE);
619 Evas_Object *object = eail_widget_get_widget(EAIL_WIDGET(selection));
621 return eail_list_mark_all_selected_state(object, EINA_FALSE);
625 * @brief Initializer of AtkSelectionIface interface
627 * @param iface AtkSelectionIface instance
629 static void atk_selection_interface_init(AtkSelectionIface *iface)
631 iface->add_selection = eail_list_add_selection;
632 iface->clear_selection = eail_list_clear_selection;
633 iface->ref_selection = eail_list_ref_selection;
634 iface->get_selection_count = eail_list_get_selection_count;
635 iface->is_child_selected = eail_list_is_child_selected;
636 iface->remove_selection = eail_list_remove_selection;
637 iface->select_all_selection = eail_list_select_all_selection;