Merge "custom eail widget implementation" into tizen
[platform/core/uifw/eail.git] / eail / eail_button.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_button.c
22  * @brief EailButton implementation
23  */
24
25 #include <Elementary.h>
26 #include "eail_button.h"
27 #include "eail_factory.h"
28 #include "eail_priv.h"
29 #include "eail_utils.h"
30
31 static void atk_text_interface_init(AtkTextIface *iface);
32
33 /**
34  * @brief Define EailButton GObject type
35  */
36 G_DEFINE_TYPE_WITH_CODE(EailButton,
37                         eail_button,
38                         EAIL_TYPE_ACTION_WIDGET,
39                         G_IMPLEMENT_INTERFACE(ATK_TYPE_TEXT,
40                                               atk_text_interface_init));
41
42 /**
43  * @brief Gets text bounded by start_offset and end_offset
44  *
45  * Use g_free() to free the returned string.
46  *
47  * @param text AtkText instance
48  * @param start_offset start position
49  * @param end_offset end position, -1 for the end of the string
50  *
51  * @return string containing the text from start_offset up to,
52  * but not including end_offset
53  */
54 static gchar*
55 eail_button_get_text(AtkText   *text,
56                      gint       start_offset,
57                      gint       end_offset)
58 {
59    gchar *string = NULL;
60    Evas_Object *widget = eail_widget_get_widget(EAIL_WIDGET(text));
61
62    if (widget)
63      string = (gchar *)elm_object_text_get(widget);
64
65    return eail_get_substring(string, start_offset, end_offset);
66 }
67
68 /**
69  * @brief Gets the character at offset
70  *
71  * @param text AtkText instance
72  * @param offset character offset
73  * @returns char representing the character at offset
74  */
75 static gunichar
76 eail_button_get_character_at_offset(AtkText    *text,
77                                     gint        offset)
78 {
79    gunichar character = '\0';
80    Evas_Object *widget = eail_widget_get_widget(EAIL_WIDGET(text));
81
82    if (widget)
83      character = g_utf8_get_char(
84          g_utf8_offset_to_pointer(elm_object_text_get(widget), offset));
85
86    return character;
87 }
88
89 /**
90  * @brief Gets the text length
91  *
92  * @param text AtkText instance
93  * @returns integer representing the text length
94  */
95 static gint
96 eail_button_get_character_count(AtkText *text)
97 {
98    gint count = 0;
99    const gchar *string_text = NULL;
100
101    Evas_Object *widget = eail_widget_get_widget(EAIL_WIDGET(text));
102
103    if (!widget) return count;
104
105    string_text = elm_object_text_get(widget);
106    if (!string_text) return count;
107
108    count = g_utf8_strlen(string_text, -1);
109
110    return count;
111 }
112
113 /**
114  * @brief AtkText interface initializer
115  *
116  * @param iface AtkTextIface instance
117  */
118 static void
119 atk_text_interface_init(AtkTextIface *iface)
120 {
121    iface->get_text = eail_button_get_text;
122    iface->get_character_at_offset = eail_button_get_character_at_offset;
123    iface->get_character_count = eail_button_get_character_count;
124 }
125
126 /**
127  * @brief Notifies ATK about button press event
128  *
129  * @param data data passed to event
130  * @param obj Evas_Object instance that received event
131  * @param event_info additional event info
132  */
133 static void
134 eail_button_atk_notify_press(void *data, Evas_Object *obj, void *event_info)
135 {
136    atk_object_notify_state_change(ATK_OBJECT(data), ATK_STATE_PRESSED, TRUE);
137 }
138
139 /**
140  * @brief Notifies ATK about button release event
141  *
142  * @param data passed to callback
143  * @param obj Evas_Object instance that raised event
144  * @param event_info additional event info
145  */
146 static void
147 eail_button_atk_notify_release(void *data, Evas_Object *obj, void *event_info)
148 {
149    atk_object_notify_state_change(ATK_OBJECT(data), ATK_STATE_PRESSED, FALSE);
150    eail_notify_child_focus_changes();
151 }
152
153 /**
154  * @brief 'click' action callback
155  *
156  * @param action AtkAction instance
157  * @param data user data passed to callback
158  *
159  * @returns TRUE if action was successfull, FALSE otherwise
160  */
161 static gboolean
162 eail_button_action_click_cb(AtkAction *action, void *data)
163 {
164    Evas_Object *widget;
165
166    widget = eail_widget_get_widget(EAIL_WIDGET(action));
167    if (!widget) return FALSE;
168
169    if ((elm_object_disabled_get(widget)) || (!evas_object_visible_get(widget)))
170      return FALSE;
171
172    evas_object_smart_callback_call(widget, "clicked", NULL);
173    eail_button_atk_notify_press(action, NULL, NULL);
174
175    return TRUE;
176 }
177
178 /**
179  * @brief 'press' action callback
180  *
181  * @param action AtkAction instance
182  * @param data user data passed to callback
183  *
184  * @returns TRUE if action was successfull, FALSE otherwise
185  */
186 static gboolean
187 eail_button_action_press_cb(AtkAction *action, void *data)
188 {
189    Evas_Object *widget;
190
191    widget = eail_widget_get_widget(EAIL_WIDGET(action));
192    if (!widget) return FALSE;
193
194    if ((elm_object_disabled_get(widget)) || (!evas_object_visible_get(widget)))
195      return FALSE;
196
197    evas_object_smart_callback_call(widget, "pressed", NULL);
198    eail_button_atk_notify_press(action, NULL, NULL);
199
200    return TRUE;
201 }
202
203 /**
204  * @brief 'release' action callback
205  *
206  * @param action AtkAction instance
207  * @param data user data passed to callback
208  *
209  * @returns TRUE if action was successfull, FALSE otherwise
210  */
211 static gboolean
212 eail_button_action_release_cb(AtkAction *action, void *data)
213 {
214    Evas_Object *widget;
215
216    widget = eail_widget_get_widget(EAIL_WIDGET(action));
217    if (!widget) return FALSE;
218
219    if ((elm_object_disabled_get(widget)) || (!evas_object_visible_get(widget)))
220      return FALSE;
221
222    evas_object_smart_callback_call(widget, "unpressed", NULL);
223    eail_button_atk_notify_release(action, NULL, NULL);
224
225    return TRUE;
226 }
227
228 /**
229  * @brief Sets EailButton actions
230  *
231  * @param action_widget EailActionWidget instance
232  */
233 static void
234 eail_button_actions_init(EailActionWidget *action_widget)
235 {
236    eail_action_widget_action_append(action_widget,
237                                     "click", NULL,
238                                     eail_button_action_click_cb);
239    eail_action_widget_action_append(action_widget,
240                                     "press", NULL,
241                                     eail_button_action_press_cb);
242    eail_action_widget_action_append(action_widget,
243                                     "release", NULL,
244                                     eail_button_action_release_cb);
245 }
246
247 /**
248  * @brief EailButton object initialization
249  *
250  * @param obj AtkObject instance
251  * @param data user set additional initialization data
252  */
253 static void
254 eail_button_initialize(AtkObject *obj, gpointer data)
255 {
256    ATK_OBJECT_CLASS(eail_button_parent_class)->initialize(obj, data);
257    obj->role = ATK_ROLE_PUSH_BUTTON;
258
259    evas_object_smart_callback_add((Evas_Object*) data, "pressed",
260                                   eail_button_atk_notify_press, obj);
261    evas_object_smart_callback_add((Evas_Object*) data, "unpressed",
262                                   eail_button_atk_notify_release, obj);
263
264    eail_button_actions_init(EAIL_ACTION_WIDGET(obj));
265 }
266
267 /**
268  * @brief Gets the list of widget's children
269  *
270  * @param widget EailWidget instance
271  *
272  * @returns Eina_list representing the list of children
273  * or NULL if widget has no children
274  */
275 static Eina_List *
276 eail_button_get_widget_children(EailWidget *widget)
277 {
278    Eina_List *list = NULL;
279    Evas_Object *child, *obj;
280
281    obj = eail_widget_get_widget(EAIL_WIDGET(widget));
282    if (obj)
283      {
284         child = elm_object_part_content_get(obj, "icon");
285         if (child && elm_object_widget_check(child))
286           list = eina_list_append(list, child);
287      }
288
289    return list;
290 }
291
292 /**
293  * @brief Gets the accessible name of obj
294  *
295  * @param obj AtkObject instance
296  *
297  * @returns string representing the accessible name of obj
298  */
299 static const gchar*
300 eail_button_get_name(AtkObject *obj)
301 {
302    Evas_Object *widget;
303    const char *atk_name;
304
305    g_return_val_if_fail(EAIL_IS_BUTTON(obj), NULL);
306
307    atk_name = ATK_OBJECT_CLASS(eail_button_parent_class)->get_name(obj);
308    if (atk_name)
309      return atk_name;
310
311    widget = eail_widget_get_widget(EAIL_WIDGET(obj));
312    if (!widget) return NULL;
313
314    return elm_object_text_get(widget);
315 }
316
317 /**
318  * @brief GObject type initialization function
319  *
320  * @param klass EailButtonClass instance
321  */
322 static void
323 eail_button_class_init(EailButtonClass *klass)
324 {
325    AtkObjectClass *atk_class = ATK_OBJECT_CLASS(klass);
326    EailWidgetClass *widget_class = EAIL_WIDGET_CLASS(klass);
327
328    atk_class->initialize = eail_button_initialize;
329    atk_class->get_name = eail_button_get_name;
330    widget_class->get_widget_children = eail_button_get_widget_children;
331 }
332
333 /**
334  * @brief EailButton instance initializer
335  *
336  * @param button EailButton instance
337  */
338 static void
339 eail_button_init(EailButton *button)
340 {
341 }