Function description fixes
[platform/core/uifw/eail.git] / eail / eail / eail_check.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_check.c
22  * @brief EailCheck implementation
23  */
24
25 #include <Elementary.h>
26
27 #include "eail_check.h"
28 #include "eail_utils.h"
29 #include "eail_factory.h"
30
31 static void atk_image_interface_init(AtkImageIface *iface);
32 static void atk_text_interface_init(AtkTextIface *iface);
33
34 /**
35  * @brief Define EailCheck GObject type
36  */
37 G_DEFINE_TYPE_WITH_CODE(EailCheck,
38                         eail_check,
39                         EAIL_TYPE_ACTION_WIDGET,
40                         G_IMPLEMENT_INTERFACE(ATK_TYPE_IMAGE,
41                                               atk_image_interface_init)
42                         G_IMPLEMENT_INTERFACE(ATK_TYPE_TEXT,
43                                               atk_text_interface_init));
44
45 /**
46  * @brief Implementation of get_image_position from AtkImage interface
47  *
48  * Gets the position of the image in the form of a point specifying the images top-left corner.
49  *
50  * @param image AtkImage instance
51  * @param [out] x horizontal coordinate or -1 if value cannot be obtained
52  * @param [out] y vertical coordinate or -1 if value cannot be obtained
53  * @param coord_type specifies whether the coordinates are relative to the screen
54  * or to the component's top level window
55  */
56 static void
57 eail_check_get_image_position(AtkImage     *image,
58                                gint         *x,
59                                gint         *y,
60                                AtkCoordType  coord_type)
61 {
62    Evas_Object *check_image;
63    Evas_Object *widget;
64    AtkObject *obj;
65
66    widget = eail_widget_get_widget(EAIL_WIDGET(image));
67    if (!widget)
68      {
69         *x = G_MININT;
70         *y = G_MININT;
71         return;
72      }
73
74    check_image = elm_object_part_content_get(widget, "icon");
75    if (check_image)
76      {
77         obj = eail_factory_get_accessible(check_image);
78         atk_image_get_image_position(ATK_IMAGE(obj), x, y, coord_type);
79      }
80    else
81      {
82         *x = G_MININT;
83         *y = G_MININT;
84      }
85 }
86
87 /**
88  * @brief Gets the width and height in pixels for the specified image
89  *
90  * The values of width and height are returned as -1 if they
91  * cannot be obtained (for instance, if the object is not onscreen).
92  *
93  * Implementation of get_image_size from AtkImage interface.
94  *
95  * @param image AtkImage instance
96  * @param [out] width image width or -1 if value cannot be obtained
97  * @param [out] height image height or -1 if value cannot be obtained
98  */
99 static void
100 eail_check_get_image_size(AtkImage *image,
101                            gint     *width,
102                            gint     *height)
103 {
104    Evas_Object *widget;
105    Evas_Object *check_image;
106    AtkObject *obj;
107
108    widget = eail_widget_get_widget(EAIL_WIDGET(image));
109    if (!widget)
110      {
111         *width = -1;
112         *height = -1;
113         return;
114      }
115
116    check_image = elm_object_part_content_get(widget, "icon");
117    if (check_image)
118      {
119         obj = eail_factory_get_accessible(check_image);
120         atk_image_get_image_size(ATK_IMAGE(obj), width, height);
121      }
122    else
123      {
124         *width = -1;
125         *height = -1;
126      }
127 }
128
129 /**
130  * @brief AtkImage interface initializer
131  *
132  * @param iface AtkImageIface instance
133  */
134 static void
135 atk_image_interface_init(AtkImageIface *iface)
136 {
137    iface->get_image_position = eail_check_get_image_position;
138    iface->get_image_size     = eail_check_get_image_size;
139 }
140
141 /**
142  * @brief Gets text bounded by start_offset and end_offset
143  *
144  * Use g_free() to free the returned string.
145  *
146  * @param text AtkText instance
147  * @param start_offset start position
148  * @param end_offset end position, -1 for the end of the string
149  * @return string containing text from start_offset up to,
150  * but not including end_offset
151  */
152 static gchar*
153 eail_check_get_text(AtkText   *text,
154                      gint       start_offset,
155                      gint       end_offset)
156 {
157    gchar *string = NULL;
158    Evas_Object *widget = eail_widget_get_widget(EAIL_WIDGET(text));
159
160    if (widget)
161      string = (gchar *)elm_object_text_get(widget);
162
163    return eail_get_substring(string, start_offset, end_offset);
164 }
165
166 /**
167  * @brief Gets the character at offset
168  *
169  * @param text AtkText instance
170  * @param offset character offset
171  * @return char representing the character at offset
172  */
173 static gunichar
174 eail_check_get_character_at_offset(AtkText    *text,
175                                     gint        offset)
176 {
177    gunichar character = '\0';
178    Evas_Object *widget = eail_widget_get_widget(EAIL_WIDGET(text));
179
180    if (widget)
181      character = g_utf8_get_char(
182          g_utf8_offset_to_pointer(elm_object_text_get(widget), offset));
183
184    return character;
185 }
186
187 /**
188  * @brief Gets the text length
189  *
190  * @param text AtkText instance
191  * @return integer representing the text length
192  */
193 static gint
194 eail_check_get_character_count(AtkText *text)
195 {
196    gint count = 0;
197    const gchar *string_text = NULL;
198
199    Evas_Object *widget = eail_widget_get_widget(EAIL_WIDGET(text));
200
201    if (!widget) return count;
202
203    string_text = elm_object_text_get(widget);
204    if (!string_text) return count;
205
206    count = g_utf8_strlen(string_text, -1);
207
208    return count;
209 }
210
211 /**
212  * @brief AtkText interface initializer
213  *
214  * Function called upon instance creation. It initializes AtkText interface
215  * implementation i.e hooks method pointers in the interface structure
216  * to the implementing class's implementation.
217  *
218  * @param iface AtkTextIface instance
219  */
220 static void
221 atk_text_interface_init(AtkTextIface *iface)
222 {
223    iface->get_text = eail_check_get_text;
224    iface->get_character_at_offset = eail_check_get_character_at_offset;
225    iface->get_character_count = eail_check_get_character_count;
226 }
227
228
229 /**
230  * @brief Callback for on_changed event
231  *
232  * Called to notify AtkObject about an object's state change.
233  *
234  * @param data callback data
235  * @param obj source object
236  * @param event_info event info
237  */
238 static void
239 eail_check_atk_notify_change(void *data, Evas_Object *obj, void *event_info)
240 {
241    Eina_Bool state = elm_check_state_get(obj);
242    atk_object_notify_state_change(ATK_OBJECT(data), ATK_STATE_CHECKED,
243                                   state == EINA_TRUE ? TRUE : FALSE);
244 }
245
246
247 /**
248  * @brief Action handler for 'click'
249  *
250  * @param action AtkAction instance (EailCheck)
251  * @param data additional data (unused here)
252  *
253  * @returns TRUE on success, FALSE otherwise
254  */
255 static gboolean
256 eail_check_action_click_cb(AtkAction *action, void *data)
257 {
258    Evas_Object *widget;
259    Eina_Bool state;
260
261    widget = eail_widget_get_widget(EAIL_WIDGET(action));
262    if (!widget) return FALSE;
263
264    if ((elm_object_disabled_get(widget)) || (!evas_object_visible_get(widget)))
265      return FALSE;
266
267    state = elm_check_state_get(widget);
268    elm_check_state_set(widget, !state);
269
270    evas_object_smart_callback_call(widget, "changed", NULL);
271    eail_check_atk_notify_change(action, widget, NULL);
272
273    return TRUE;
274 }
275
276 /**
277  * @brief Initializer for actions defined in EailCheck
278  *
279  * @param action_widget EailActionWidget implementation to be filled
280  */
281 static void
282 eail_check_actions_init(EailActionWidget *action_widget)
283 {
284    eail_action_widget_action_append(action_widget, "click", NULL,
285                                     eail_check_action_click_cb);
286 }
287
288 /**
289  * @brief Gets a reference to the state set of the accessible
290  *
291  * The caller must unreference it when it is no longer needed.
292  *
293  * Implementation of ref_state_set from AtkObject.
294  *
295  * @param obj AtkObject instance
296  *
297  * @returns AtkStateSet representing the state set
298  * of the accessible
299  */
300 static AtkStateSet*
301 eail_check_ref_state_set(AtkObject *obj)
302 {
303    Evas_Object *widget = eail_widget_get_widget(EAIL_WIDGET(obj));
304    AtkStateSet *state_set =
305        ATK_OBJECT_CLASS(eail_check_parent_class)->ref_state_set(obj);
306
307    if (NULL == widget)
308      {
309         atk_state_set_add_state(state_set, ATK_STATE_DEFUNCT);
310         return state_set;
311      }
312    if (elm_check_state_get(widget))
313      {
314         atk_state_set_add_state(state_set, ATK_STATE_CHECKED);
315      }
316
317    return state_set;
318 }
319
320 /**
321  * @brief Gets the accessible name of obj
322  *
323  * @param obj AtkObject instance
324  *
325  * @returns string representing the accessible name of obj
326  */
327 static const gchar*
328 eail_check_get_name(AtkObject *obj)
329 {
330    Evas_Object *widget;
331    const char *atk_name;
332
333    g_return_val_if_fail(EAIL_IS_CHECK(obj), NULL);
334
335    atk_name = ATK_OBJECT_CLASS(eail_check_parent_class)->get_name(obj);
336    if (atk_name)
337      return atk_name;
338
339    widget = eail_widget_get_widget(EAIL_WIDGET(obj));
340    if (!widget) return NULL;
341
342    return elm_object_text_get(widget);
343 }
344
345 /**
346  * @brief Gets the list of widget's children
347  *
348  * @param widget EailWidget instance
349  *
350  * @return Eina_list representing the list of children
351  * or NULL if widget has no children
352  */
353 static Eina_List *
354 eail_check_get_widget_children(EailWidget *widget)
355 {
356    Eina_List *list = NULL;
357    Evas_Object *child, *obj;
358
359    obj = eail_widget_get_widget(EAIL_WIDGET(widget));
360    if (obj)
361      {
362         child = elm_object_part_content_get(obj, "icon");
363         if (child && elm_object_widget_check(child))
364           list = eina_list_append(list, child);
365      }
366
367    return list;
368 }
369
370 /**
371  * @brief EailCheck instance initialization
372  *
373  * @param check AtkObject instance
374  */
375 static void
376 eail_check_init(EailCheck *check)
377 {
378 }
379
380 /**
381  * @brief EailCheck object initialization
382  *
383  * @param obj EailCheck instance
384  * @param data user set addtional initailization data
385  */
386 static void
387 eail_check_initialize(AtkObject *obj, gpointer data)
388 {
389    ATK_OBJECT_CLASS(eail_check_parent_class)->initialize(obj, data);
390    obj->role = ATK_ROLE_CHECK_BOX;
391
392    evas_object_smart_callback_add((Evas_Object*) data, "changed",
393                                   eail_check_atk_notify_change,
394                                   obj);
395
396    eail_check_actions_init(EAIL_ACTION_WIDGET(obj));
397 }
398
399 /**
400  * @brief GObject type initialization function
401  *
402  * @param klass EailCheckClass instance
403  */
404 static void
405 eail_check_class_init(EailCheckClass *klass)
406 {
407    AtkObjectClass *class = ATK_OBJECT_CLASS(klass);
408    EailWidgetClass *widget_class = EAIL_WIDGET_CLASS(klass);
409
410    class->initialize = eail_check_initialize;
411    class->ref_state_set = eail_check_ref_state_set;
412    class->get_name = eail_check_get_name;
413    widget_class->get_widget_children = eail_check_get_widget_children;
414 }