Merge "custom eail widget implementation" into tizen
[platform/core/uifw/eail.git] / eail / eail_naviframe_page.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_naviframe_page.c
22  * @brief EailNaviframePage implementation
23  */
24
25 #include "eail_naviframe_page.h"
26 #include "eail_naviframe.h"
27 #include "eail_factory.h"
28 #include "eail_widget.h"
29 #include "eail_priv.h"
30
31 static void atk_component_interface_init(AtkComponentIface *iface);
32
33 /**
34  * Defines EailNaviframePage type
35  */
36 G_DEFINE_TYPE_WITH_CODE(EailNaviframePage,
37                         eail_naviframe_page,
38                         ATK_TYPE_OBJECT,
39                         G_IMPLEMENT_INTERFACE(ATK_TYPE_COMPONENT,
40                                               atk_component_interface_init));
41
42 /**
43  * @brief Creates a new instance of an accessible naviframe page
44  *
45  * @param naviframe AtkObject instance
46  * @param navi_tab_item Elm_Object_Item instance
47  * @returns AtkObject representing the accessible naviframe page
48  */
49 AtkObject *
50 eail_naviframe_page_new(AtkObject *naviframe, Elm_Object_Item *navi_tab_item)
51 {
52    AtkObject *atk_object;
53    EailNaviframePage *page;
54    Evas_Object *o, *widget;
55
56    g_return_val_if_fail(EAIL_IS_NAVIFRAME(naviframe), NULL);
57
58    widget = eail_widget_get_widget(EAIL_WIDGET(naviframe));
59
60    g_return_val_if_fail(widget != NULL, NULL);
61
62    atk_object = g_object_new(EAIL_TYPE_NAVIFRAME_PAGE, NULL);
63    page = EAIL_NAVIFRAME_PAGE(atk_object);
64
65    page->naviframe = widget;
66
67    page->page = navi_tab_item;
68
69    page->child_count = 0;
70
71    o = elm_object_item_part_content_get(page->page, "prev_btn");
72    if (o && elm_object_widget_check(o))
73      page->content[page->child_count++] = o;
74
75    o = elm_object_item_part_content_get(page->page, "icon");
76    if (o && elm_object_widget_check(o))
77      page->content[page->child_count++] = o;
78
79    o = elm_object_item_part_content_get(page->page, "next_btn");
80    if (o && elm_object_widget_check(o))
81      page->content[page->child_count++] = o;
82
83    o = elm_object_item_part_content_get(page->page, "default");
84    if (o && elm_object_widget_check(o))
85      page->content[page->child_count++] = o;
86
87    page->parent_naviframe = naviframe;
88
89    atk_object->layer = ATK_LAYER_WIDGET;
90
91    return atk_object;
92 }
93
94 /**
95  * @brief Returns the accessible name if assigned, title or subtitle otherwise
96  *
97  * Implementation of atk_object_get_name from AtkObject.
98  *
99  * @param obj AtkObject instance
100  * @returns string representing the accessible name if assigned, title or subtitle otherwise
101  */
102 static const char *
103 eail_naviframe_page_name_get(AtkObject *obj)
104 {
105    const gchar *atk_name = NULL;
106
107    g_return_val_if_fail(EAIL_IS_NAVIFRAME_PAGE(obj), NULL);
108
109    /* returning name from ATK default implementation if available */
110    atk_name = ATK_OBJECT_CLASS(eail_naviframe_page_parent_class)->get_name(obj);
111    if (atk_name) return atk_name;
112
113    EailNaviframePage *page = EAIL_NAVIFRAME_PAGE(obj);
114    if (page->name != NULL) return page->name;
115
116    const char *title = elm_object_item_part_text_get(page->page, "default");
117    const char *subtitle = elm_object_item_part_text_get(page->page, "subtitle");
118
119    if (subtitle != NULL)
120      page->name = eina_stringshare_printf("%s, %s", title, subtitle);
121    else
122      page->name = eina_stringshare_add(title);
123
124    return page->name;
125 }
126
127 /**
128  * @brief Initiates EailNaviframePage
129  *
130  * @param naviframe_page EailNaviframePage instance
131  */
132 static void
133 eail_naviframe_page_init(EailNaviframePage *naviframe_page)
134 {
135 }
136
137 /**
138  * @brief Initializes EailNaviframPage
139  *
140  * @param obj AtkObject instance
141  * @param data user data
142  */
143 static void
144 eail_naviframe_page_initialize(AtkObject *obj, gpointer data)
145 {
146    ATK_OBJECT_CLASS(eail_naviframe_page_parent_class)->initialize(obj, data);
147
148    obj->role = ATK_ROLE_PAGE_TAB;
149    obj->layer = ATK_LAYER_WIDGET;
150 }
151
152 /**
153  * @brief Finalizes object
154  *
155  * @param obj AtkObject instance
156  */
157 static void
158 eail_naviframe_page_finalize(GObject *obj)
159 {
160    EailNaviframePage *page = EAIL_NAVIFRAME_PAGE(obj);
161
162    eina_stringshare_del(page->name);
163
164    if (page->page)
165      eail_factory_unregister_item_from_cache(page->page);
166
167    G_OBJECT_CLASS(eail_naviframe_page_parent_class)->finalize(obj);
168 }
169
170 /**
171  * @brief Gets the number of accessible children of obj
172  *
173  * @param obj AtkObject instance
174  *
175  * @returns integer representing the number of children
176  */
177 static gint
178 eail_naviframe_page_n_children_get(AtkObject *obj)
179 {
180    EailNaviframePage *page;
181
182    g_return_val_if_fail(EAIL_IS_NAVIFRAME_PAGE(obj), 0);
183    page = EAIL_NAVIFRAME_PAGE(obj);
184
185    return page->child_count;
186 }
187
188 /**
189  * @brief Gets obj's parent
190  *
191  * @param obj AtkObject instance
192  *
193  * @returns AtkObject representing the parent of obj
194  */
195 static AtkObject *
196 eail_naviframe_page_parent_get(AtkObject *obj)
197 {
198    EailNaviframePage *page;
199
200    g_return_val_if_fail(EAIL_IS_NAVIFRAME_PAGE(obj), NULL);
201
202    page = EAIL_NAVIFRAME_PAGE(obj);
203
204    return ATK_OBJECT(page->parent_naviframe);
205 }
206
207 /**
208  * @brief Gets a reference to the specified child of obj
209  *
210  * @param obj AtkObject instance
211  * @param i child index
212  *
213  * @returns AtkObject representing the specified child
214  */
215 static AtkObject *
216 eail_naviframe_page_ref_child(AtkObject *obj, gint i)
217 {
218    EailNaviframePage *page;
219    AtkObject *atk_obj_child = NULL;
220
221    g_return_val_if_fail(EAIL_IS_NAVIFRAME_PAGE(obj), NULL);
222
223    page = EAIL_NAVIFRAME_PAGE(obj);
224    if (i >= page->child_count) return NULL;
225
226    atk_obj_child = eail_factory_get_accessible(page->content[i]);
227
228    g_object_ref(atk_obj_child);
229    return atk_obj_child;
230 }
231
232 /**
233  * @brief Gets the index of obj in parent object
234  *
235  * @param obj AtkObject instance
236  *
237  * @returns integer representing the index of object
238  */
239 static gint
240 eail_naviframe_page_index_in_parent_get(AtkObject *obj)
241 {
242    EailNaviframePage *page = NULL;
243    Eina_List *list = NULL;
244    gint pos = -1, i = 0;
245
246    if (!EAIL_IS_NAVIFRAME_PAGE(obj))
247      {
248         ERR("Not a naviframe page");
249         return pos;
250      }
251
252    page = EAIL_NAVIFRAME_PAGE(obj);
253    if (!page->naviframe) return pos;
254
255    list = elm_naviframe_items_get(page->naviframe);
256    for (i = 0; i < eina_list_count(list); ++i)
257      {
258         if (page->page == eina_list_nth(list, i))
259           {
260              pos = i;
261              break;
262           }
263      }
264
265    eina_list_free(list);
266    return pos;
267 }
268
269 /**
270  * @brief Gets the state set of the accessible object
271  *
272  * @param obj AtkObject instance
273  *
274  * @returns AtkStateSet representing the state set of the accessible object
275  */
276 static AtkStateSet *
277 eail_naviframe_page_ref_state_set(AtkObject *obj)
278 {
279    EailNaviframePage *page;
280    AtkStateSet *state_set;
281    Evas_Object *widget;
282
283    g_return_val_if_fail(EAIL_IS_NAVIFRAME_PAGE(obj), NULL);
284
285    page = EAIL_NAVIFRAME_PAGE(obj);
286    if (!page->naviframe) return NULL;
287
288    widget = elm_object_part_content_get(page->naviframe, "default");
289
290    state_set = atk_state_set_new();
291
292    /* only item-page on top is visible*/
293    if (elm_naviframe_top_item_get(page->naviframe) == page->page)
294      {
295         atk_state_set_add_state(state_set, ATK_STATE_SHOWING);
296         atk_state_set_add_state(state_set, ATK_STATE_VISIBLE);
297      }
298
299    if (!elm_object_disabled_get(widget))
300      atk_state_set_add_state(state_set, ATK_STATE_ENABLED);
301
302    return state_set;
303 }
304
305 /**
306  * @brief EailNaviframePage class initializer
307  *
308  * @param klass EailNaviframePageClass instance
309  */
310 static void
311 eail_naviframe_page_class_init(EailNaviframePageClass *klass)
312 {
313    GObjectClass *g_object_class = G_OBJECT_CLASS(klass);
314    AtkObjectClass *atk_class = ATK_OBJECT_CLASS(klass);
315
316    atk_class->initialize = eail_naviframe_page_initialize;
317    atk_class->get_name = eail_naviframe_page_name_get;
318    atk_class->get_parent = eail_naviframe_page_parent_get;
319    atk_class->get_n_children = eail_naviframe_page_n_children_get;
320    atk_class->ref_child = eail_naviframe_page_ref_child;
321    atk_class->ref_state_set = eail_naviframe_page_ref_state_set;
322    atk_class->get_index_in_parent = eail_naviframe_page_index_in_parent_get;
323
324    g_object_class->finalize = eail_naviframe_page_finalize;
325 }
326
327 /**
328  * @brief Gets the rectangle which gives the extent of the component
329  *
330  * Implementation of get_extents from AtkComponent interface.
331  *
332  * @param component AtkComponent instance
333  * @param [out] x x coordinate
334  * @param [out] y y coordinate
335  * @param [out] width width of the rectangle
336  * @param [out] height height of the rectangle
337  * @param coord_type specifies whether the coordinates are relative to the screen or to the component's top level window
338  */
339 static void
340 eail_naviframe_page_get_extents(AtkComponent *component,
341                                 gint *x,
342                                 gint *y,
343                                 gint *width,
344                                 gint *height,
345                                 AtkCoordType coord_type)
346 {
347    EailNaviframePage *page;
348    Evas_Object *widget;
349    g_return_if_fail(EAIL_IS_NAVIFRAME_PAGE(component));
350
351    page = EAIL_NAVIFRAME_PAGE(component);
352    *x = *y = *width = *height = G_MININT;
353    if (!page->naviframe) return;
354
355    widget = page->naviframe;
356
357    evas_object_geometry_get(widget, x, y, width, height);
358    if (coord_type == ATK_XY_SCREEN)
359      {
360         int ee_x, ee_y;
361
362         Ecore_Evas *ee = ecore_evas_ecore_evas_get(
363            evas_object_evas_get(widget));
364         ecore_evas_geometry_get(ee, &ee_x, &ee_y, NULL, NULL);
365         *x += ee_x;
366         *y += ee_y;
367      }
368 }
369
370 /**
371  * @brief AtkComponent interface initialization
372  *
373  * @param iface AtkComponentIface instance
374  */
375 static void atk_component_interface_init(AtkComponentIface *iface)
376 {
377    g_return_if_fail(iface != NULL);
378
379    iface->get_extents = eail_naviframe_page_get_extents;
380 }