Merge "custom eail widget implementation" into tizen
[platform/core/uifw/eail.git] / eail / eail_layout.c
1 /*
2  * Copyright (c) 2013 Samsung Electronics Co., Ltd.
3  *
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.
8  *
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.
13  *
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.
18  */
19
20 /**
21  * @file eail_layout.c
22  *
23  * @brief EailLayout implementation
24 */
25
26 #include <Elementary.h>
27
28 #include "eail_layout.h"
29 #include "eail_dynamic_content.h"
30 #include "eail_utils.h"
31 #include "eail_priv.h"
32
33 static void eail_dynamic_content_interface_init(EailDynamicContentIface *iface);
34
35 /**
36  * @brief Define EailLayout GObject type
37  *
38  * It extends EAIL_TYPE_WIDGET
39  */
40 G_DEFINE_TYPE_WITH_CODE(EailLayout, eail_layout, EAIL_TYPE_WIDGET,
41                     G_IMPLEMENT_INTERFACE(EAIL_TYPE_DYNAMIC_CONTENT,
42                                           eail_dynamic_content_interface_init));
43
44 /**
45  * @brief Gets elementary widgets from a layout edje object
46  *
47  * Iterates over edje smart objects and if an object is an elementary widget
48  * then it is appended to the list.
49  *
50  * @param edje layout edje instance
51  *
52  * @returns Eina_List representing the list of Elementary widgets
53  */
54 static Eina_List *
55 _get_widgets_from_edje(const Evas_Object *edje)
56 {
57    Evas_Object *o;
58    Eina_List *widgets, *l, *list = evas_object_smart_members_get(edje);
59
60    widgets = NULL;
61    EINA_LIST_FOREACH(list, l, o)
62      {
63         if (elm_object_widget_check(o))
64           widgets = eina_list_append(widgets, o);
65      }
66
67    return widgets;
68 }
69
70 /**
71  * @brief Gets accessible children of object
72  *
73  * Implementation of get_widget_children from EailWidget.
74  *
75  * @param object EailWidget instance
76  *
77  * @returns Eina_List representing the list of object's children
78  */
79 static Eina_List*
80 eail_layout_widget_children_get(EailWidget *object)
81 {
82    Evas_Object *edje;
83    Evas_Object *widget = eail_widget_get_widget(object);
84
85    if (!widget) return NULL;
86    edje = elm_layout_edje_get(widget);
87
88    return _get_widgets_from_edje(edje);
89 }
90
91 /**
92  * @brief Initializes EailLayout object
93  *
94  * @param object AtkObject instance
95  * @param data user data passed to initialization
96  */
97 static void
98 eail_layout_initialize(AtkObject *object, gpointer data)
99 {
100    ATK_OBJECT_CLASS(eail_layout_parent_class)->initialize(object, data);
101    EailLayout *eail_layout = NULL;
102    object->role = ATK_ROLE_FILLER;
103
104    if (!EAIL_IS_LAYOUT(object))
105      {
106         DBG("Not EAIL_LAYOUT!. Returning");
107         return;
108      }
109
110    /* storing last numbers of children to be for checking if children-changed
111     * signal has to be propagated */
112    eail_layout = EAIL_LAYOUT(object);
113    eail_layout->child_count_last = atk_object_get_n_accessible_children(object);
114 }
115
116 /**
117  * @brief Initiates EailLayout instance
118  *
119  * @param layout EailLayout instance
120  */
121 static void
122 eail_layout_init(EailLayout *layout)
123 {
124 }
125
126 /**
127  * @brief Initiates EailLayout class
128  *
129  * @param klass EailLayoutClass instance
130  */
131 static void
132 eail_layout_class_init(EailLayoutClass *klass)
133 {
134    AtkObjectClass *atk_class = ATK_OBJECT_CLASS(klass);
135    EailWidgetClass *widget_class = EAIL_WIDGET_CLASS(klass);
136
137    atk_class->initialize = eail_layout_initialize;
138    widget_class->get_widget_children = eail_layout_widget_children_get;
139 }
140
141 /**
142  * @param dynamic_content_holder an EailDynamicContent object (EailLayout)
143  */
144 void
145 eail_layout_update_descendants(EailDynamicContent *dynamic_content_holder)
146 {
147    gint n_children = 0;
148    EailLayout *layout = NULL;
149    if (!EAIL_IS_LAYOUT(dynamic_content_holder))
150      {
151         DBG("No EailLayout found. Returning");
152         return;
153      }
154
155    layout = EAIL_LAYOUT(dynamic_content_holder);
156
157    n_children = atk_object_get_n_accessible_children(ATK_OBJECT(layout));
158    if (n_children && n_children > layout->child_count_last)
159      {
160         eail_emit_children_changed(TRUE, ATK_OBJECT(layout), n_children - 1);
161      }
162    else if (n_children < layout->child_count_last)
163      {
164          eail_emit_children_changed
165                      (FALSE, ATK_OBJECT(layout), layout->child_count_last);
166      }
167
168    layout->child_count_last = n_children;
169 }
170
171 /**
172  * @brief Initializer for dynamic content interface, used for handling objects
173  * children hierarchy changes
174  *
175  * @param iface an EailDynamicContentIface
176  */
177 static void
178 eail_dynamic_content_interface_init(EailDynamicContentIface *iface)
179 {
180    iface->update_hierarchy = eail_layout_update_descendants;
181 }