Merge "custom eail widget implementation" into tizen
[platform/core/uifw/eail.git] / eail / eail_radio_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_radio_button.c
22  * @brief EailRadioButton implementation
23  */
24
25 #include <atk/atk.h>
26 #include <Elementary.h>
27
28 #include "eail_radio_button.h"
29 #include "eail_priv.h"
30
31 static void atk_action_interface_init(AtkActionIface *iface);
32
33 /**
34  * @brief Definition of EailRadioButton type
35  */
36 G_DEFINE_TYPE_WITH_CODE(EailRadioButton,
37                         eail_radio_button,
38                         EAIL_TYPE_BUTTON,
39                         G_IMPLEMENT_INTERFACE(ATK_TYPE_ACTION,
40                                               atk_action_interface_init));
41
42 /**
43  * @brief Callback for 'on_change' event
44  *
45  * Called to notify AtkObject about state change.
46  *
47  * @param data user data passed to callback
48  * @param obj source object
49  * @param event_info event info
50  */
51 static void
52 _on_change(void *data, Evas_Object *obj, void *event_info)
53 {
54    EailRadioButton *button = EAIL_RADIO_BUTTON(data);
55    button->state = elm_radio_state_value_get(obj) ? EINA_TRUE : EINA_FALSE;
56
57    atk_object_notify_state_change(ATK_OBJECT(button), ATK_STATE_CHECKED,
58                                   button->state == EINA_TRUE ? TRUE : FALSE);
59 }
60
61 /**
62  * @brief Gets a reference to the state set of the accessible
63  *
64  * The caller must unreference it when it is no longer needed.
65  *
66  * Implementation of ref_state_set from AtkObject interface.
67  *
68  * @param obj AtkObject instance
69  *
70  * @returns AtkStateSet representing the state set of the accessible
71  */
72 static AtkStateSet*
73 eail_radio_button_ref_state_set(AtkObject *obj)
74 {
75    Evas_Object *widget = eail_widget_get_widget(EAIL_WIDGET(obj));
76    AtkStateSet *state_set =
77       ATK_OBJECT_CLASS(eail_radio_button_parent_class)->ref_state_set(obj);
78    if (widget==NULL)
79      {
80         atk_state_set_add_state(state_set, ATK_STATE_DEFUNCT);
81         return state_set;
82      }
83
84    /* get group value*/
85    int selected_value  = elm_radio_value_get(widget);
86    int widget_value = elm_radio_state_value_get(widget);
87
88    if (selected_value == widget_value)
89      {
90         atk_state_set_add_state(state_set, ATK_STATE_CHECKED);
91      }
92
93    return state_set;
94 }
95
96 /**
97  * @brief Initialize EailRadionButton as AtkObject
98  *
99  * @param obj AtkObject instance
100  * @param data user data passed to initialization
101  */
102 static void
103 eail_radio_button_initialize(AtkObject *obj, gpointer data)
104 {
105     ATK_OBJECT_CLASS(eail_radio_button_parent_class)->initialize(obj, data);
106     Evas_Object *widget = (Evas_Object *) data;
107     EailRadioButton *radio = EAIL_RADIO_BUTTON(obj);
108     int value = elm_radio_state_value_get(widget);
109     int selected = elm_radio_value_get(widget);
110     if (selected == value)
111       {
112         radio->state = EINA_TRUE;
113       }
114     evas_object_smart_callback_add(widget, "changed", _on_change, obj);
115
116     obj->role = ATK_ROLE_RADIO_BUTTON;
117 }
118
119 /**
120  * @brief Initialize EailRadioButton object
121  *
122  * @param radio_button EailRadioButton instance
123  */
124 static void
125 eail_radio_button_init(EailRadioButton *radio_button)
126 {
127    radio_button->click_description = NULL;
128    radio_button->state = EINA_FALSE;
129 }
130
131 /**
132  * @brief EailRadioButton finalize function
133  *
134  * @param object GObject instance
135  */
136 static void
137 eail_radio_button_finalize(GObject *object)
138 {
139    EailRadioButton *button = EAIL_RADIO_BUTTON(object);
140    if (button->click_description) free(button->click_description);
141    G_OBJECT_CLASS(eail_radio_button_parent_class)->finalize(object);
142 }
143
144 /**
145  * @brief Object class initialization
146  *
147  * @param klass EailRadioButtonClass instance
148  */
149 static void
150 eail_radio_button_class_init(EailRadioButtonClass *klass)
151 {
152     AtkObjectClass *class = ATK_OBJECT_CLASS(klass);
153     GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
154     class->initialize = eail_radio_button_initialize;
155     class->ref_state_set = eail_radio_button_ref_state_set;
156     gobject_class->finalize = eail_radio_button_finalize;
157 }
158
159 /**
160  * @brief Gets the number of accessible actions available on the object
161  *
162  * If there are more than one, the first one is considered
163  * the "default" action of the object.
164  *
165  * Implementation of get_n_actions from AtkAction interface.
166  *
167  * @param action AtkAction instance
168  *
169  * @returns integer representing the number of available actions
170  */
171 static int
172 eail_radio_button_n_action_get(AtkAction *action)
173 {
174    return 1;
175 }
176
177 /**
178  * @brief Gets the name of the specified action of the object
179  *
180  * Implementation of get_action_name from AtkAction interface.
181  *
182  * @param action AtkAction instance
183  * @param i index of action
184  *
185  * @returns string representing the name of the specified action
186  */
187 static const char*
188 eail_radio_button_action_name_get(AtkAction *action, int i)
189 {
190    const char *action_name;
191    switch (i)
192      {
193       case 0:
194          /*click - This is called whenever the user changes the state of one of*/
195          /*the radio objects within the group of radio objects that work together. */
196          action_name = "click";
197          break;
198       default:
199          action_name = NULL;
200          break;
201      }
202    return action_name;
203 }
204
205 /**
206  * @brief Sets a description of the specified action of the object
207  *
208  * Implementation of set_description from AtkAction.
209  *
210  * @param action AtkAction instance
211  * @param i action index
212  * @param description action's description to set
213  *
214  * @returns TRUE on success, FALSE otherwise
215  */
216 static gboolean
217 eail_radio_button_description_set(AtkAction *action, gint i, const char *description)
218 {
219    if (i != 0) return FALSE;
220
221    EailRadioButton *button = EAIL_RADIO_BUTTON(action);
222    if (button->click_description) free(button->click_description);
223    button->click_description = g_strdup(description);
224    return TRUE;
225 }
226
227 /**
228  * @brief Gets the description of the specified action of the object
229  *
230  * Implementation of get_description from AtkAction interface.
231  *
232  * @param action AtkAction instance
233  * @param i index of action
234  *
235  * @returns string representing the description of the specified action
236  */
237 static const char*
238 eail_radio_button_description_get(AtkAction *action, gint i)
239 {
240    if (i != 0) return NULL;
241
242    EailRadioButton *button = EAIL_RADIO_BUTTON(action);
243    return button->click_description;
244 }
245
246 /**
247  * @brief Performs the specified action on the object
248  *
249  * Implementation of do_action from AtkAction interface.
250  *
251  * @param action AtkAction instance
252  * @param i action index
253  *
254  * @returns TRUE on success, FALSE otherwise
255  */
256 static gboolean
257 eail_radio_button_do_action(AtkAction *action, int i)
258 {
259    Evas_Object *obj = eail_widget_get_widget(EAIL_WIDGET(action));
260    EailRadioButton *button = EAIL_RADIO_BUTTON(action);
261    if (button->state == EINA_TRUE) return FALSE;
262    if ((elm_object_disabled_get(obj)) || (!evas_object_visible_get(obj)))
263      return FALSE;
264    const char *action_name = atk_action_get_name(action, i);
265    if (action_name == NULL) return FALSE;
266    int state_value = elm_radio_state_value_get(obj);
267    elm_radio_value_set(obj, state_value);
268    button->state = EINA_TRUE;
269
270    if (!g_strcmp0(action_name, "click"))
271         evas_object_smart_callback_call(obj, "changed", NULL);
272
273    return TRUE;
274 }
275
276 /**
277  * @brief AtkAction interface initialization
278  *
279  * @param iface AtkActionIface instance
280  */
281 static void
282 atk_action_interface_init(AtkActionIface *iface)
283 {
284    g_return_if_fail(iface != NULL);
285
286    iface->do_action = eail_radio_button_do_action;
287    iface->get_n_actions = eail_radio_button_n_action_get;
288    iface->get_description = eail_radio_button_description_get;
289    iface->get_name = eail_radio_button_action_name_get;
290    iface->set_description = eail_radio_button_description_set;
291 }