Merge "custom eail widget implementation" into tizen
[platform/core/uifw/eail.git] / eail / eail_app.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_app.c
22  * @brief Elementary application implementation
23  */
24
25 #include <Elementary.h>
26
27 #include "eail_app.h"
28 #include "eail_factory.h"
29 #include "eail_dynamic_content.h"
30 #include "eail_utils.h"
31 #include "eail_priv.h"
32
33 /** @brief This is defined and filled in elementary.*/
34 extern Eina_List *_elm_win_list;
35
36 static void eail_dynamic_content_interface_init(EailDynamicContentIface *iface);
37
38 /**
39  * @brief Definition of EailApp as GObject
40  *
41  * EailApp is extended ATK_TYPE_OBJECT with EAIL_TYPE_DYNAMIC_CONTENT iface
42  * implemented
43  */
44
45 G_DEFINE_TYPE_WITH_CODE(EailApp, eail_app, ATK_TYPE_OBJECT,
46                     G_IMPLEMENT_INTERFACE(EAIL_TYPE_DYNAMIC_CONTENT,
47                                           eail_dynamic_content_interface_init));
48
49 /**
50  * @brief Initializer for AtkObjectClass
51  *
52  * @param obj AtkObject instance to be initialized
53  * @param data additional initialization data (Evas_Object*)
54  */
55 static void
56 eail_app_initialize(AtkObject *obj, gpointer data)
57 {
58    int argc;
59    char **argv;
60    EailApp *eail_app = NULL;
61
62    ATK_OBJECT_CLASS(eail_app_parent_class)->initialize(obj, data);
63
64    ecore_app_args_get(&argc, &argv);
65    obj->name = argv ? g_strdup((gchar *)ecore_file_file_get(argv[0])) : NULL;
66    obj->role = ATK_ROLE_APPLICATION;
67    obj->accessible_parent = NULL;
68
69    /* storing last numbers of children to be for checking if children-changed
70      * signal has to be propagated */
71    eail_app = EAIL_APP(obj);
72    eail_app->child_count_last = atk_object_get_n_accessible_children(obj);
73 }
74
75 /**
76  * @brief Destructor for EailApp object
77  * @param obj GObject to be freed
78  */
79 static void
80 eail_app_class_finalize(GObject *obj)
81 {
82    G_OBJECT_CLASS(eail_app_parent_class)->finalize(obj);
83 }
84
85 /**
86  * @brief Gets the number of accessible children of the accessible
87  *
88  * Implementation of AtkObject->get_n_children callback.
89  *
90  * @param obj AtkObject instance
91  *
92  * @returns integer representing the number of accessible children of
93  * the accessible
94  */
95 static gint
96 eail_app_get_n_children(AtkObject *obj)
97 {
98    return eina_list_count(_elm_win_list);
99 }
100
101 /**
102  * @brief Gets a reference to the specified accessible child of the object.
103  *
104  * The accessible children are 0-based so the first accessible child is at index 0,
105  * the second at index 1 and so on.
106  *
107  * Implementation of AtkObject->ref_child callback.
108  *
109  * @param obj AtkObject instance
110  * @param i index number
111  *
112  * @returns AtkObject representing the specified accessible child of the
113  * accessible
114  */
115 static AtkObject *
116 eail_app_ref_child(AtkObject *obj, gint i)
117 {
118    AtkObject *child = NULL;
119
120    if (eina_list_count(_elm_win_list) > i)
121      {
122         Evas_Object *tmp = eina_list_nth(_elm_win_list, i);
123         child = eail_factory_get_accessible(tmp);
124         g_object_ref(child);
125      }
126
127    return child;
128 }
129
130 /**
131  * @brief Initializer for GObject class
132  * @param app EailApp instance to be initialized
133  */
134 static void
135 eail_app_init(EailApp *app)
136 {
137 }
138
139 /**
140  * @brief Initializer for GObject EailAppClass class
141  *
142  * Defines callbacks for base AtkObject.
143  *
144  * @param klass EailAppClass instance to be filled
145  */
146 static void
147 eail_app_class_init(EailAppClass *klass)
148 {
149    AtkObjectClass *atk_class = ATK_OBJECT_CLASS(klass);
150    GObjectClass *g_object_class = G_OBJECT_CLASS(klass);
151
152    atk_class->initialize = eail_app_initialize;
153    atk_class->get_n_children = eail_app_get_n_children;
154    atk_class->ref_child = eail_app_ref_child;
155
156    g_object_class->finalize = eail_app_class_finalize;
157 }
158
159 /**
160  * @param dynamic_content_holder an EailDynamicContent object (EailApp)
161  */
162 void
163 eail_app_update_descendants(EailDynamicContent *dynamic_content_holder)
164 {
165    DBG(">");
166    gint n_children = 0;
167    EailApp *app = NULL;
168    if (!EAIL_IS_APP(dynamic_content_holder))
169      {
170         DBG("No EailApp found. Returning");
171         return;
172      }
173
174    app = EAIL_APP(dynamic_content_holder);
175
176    n_children = atk_object_get_n_accessible_children(ATK_OBJECT(app));
177    if (n_children && n_children > app->child_count_last)
178      {
179          DBG("emit changed add");
180         eail_emit_children_changed(TRUE, ATK_OBJECT(app), n_children - 1);
181      }
182    else if (n_children < app->child_count_last)
183      {
184          DBG("emit changed remove");
185          eail_emit_children_changed
186                      (FALSE, ATK_OBJECT(app), app->child_count_last);
187      }
188
189    app->child_count_last = n_children;
190 }
191
192 /**
193  * @brief Initializer for dynamic content interface, used for handling objects
194  * children hierarchy changes
195  *
196  * @param iface an EailDynamicContentIface
197  */
198 static void
199 eail_dynamic_content_interface_init(EailDynamicContentIface *iface)
200 {
201    iface->update_hierarchy = eail_app_update_descendants;
202 }