Merge "custom eail widget implementation" into tizen
[platform/core/uifw/eail.git] / eail / eail_action_widget.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_action_widget.c
22  * @brief EailActionWidget implementation
23  */
24
25 #include <Elementary.h>
26
27 #include "eail_action_widget.h"
28 #include "eail_priv.h"
29
30 static void atk_action_interface_init(AtkActionIface *iface);
31
32 /** @brief ActionObject structure for objects stored in actions list */
33 typedef struct _EailActionObj EailActionObj;
34
35 /** @brief ActionObject structure for objects stored in actions list
36  */
37 struct _EailActionObj
38 {
39    const gchar * name;/*!< \brief action name */
40    const gchar * keybinding;/*!< \brief action keybinding */
41    gchar * description;/*!< \brief action description */
42    Eail_Do_Action_Cb action;/*!< \brief action callback */
43 };
44
45 /**
46  * @brief Definition of EailActionWidget as GObject
47  */
48 G_DEFINE_TYPE_WITH_CODE(EailActionWidget,
49                         eail_action_widget,
50                         EAIL_TYPE_WIDGET,
51                         G_IMPLEMENT_INTERFACE(ATK_TYPE_ACTION,
52                                               atk_action_interface_init));
53
54 /**
55  * @brief Initializer for AtkObjectClass
56  *
57  * @param obj AtkObject(EailActionWidget) instance to be initialized
58  * @param data additional initialization data
59  */
60 static void
61 eail_action_widget_initialize(AtkObject *obj, gpointer data)
62 {
63    ATK_OBJECT_CLASS(eail_action_widget_parent_class)->initialize(obj, data);
64
65    EailActionWidget *widget = EAIL_ACTION_WIDGET(obj);
66
67    widget->action_objs = NULL;
68 }
69
70 /**
71  * @brief Initializer for GObject class
72  *
73  * @param action_widget AtkOject(EailActionWidget) instance to be initialized
74  */
75 static void
76 eail_action_widget_init(EailActionWidget *action_widget)
77 {
78 }
79
80 /**
81  * @brief Deallocates memory for EailActionObj
82  *
83  * @param action_obj EailActionObj instance to be freed
84  */
85 static void
86 eail_action_obj_free(EailActionObj *action_obj)
87 {
88    g_return_if_fail(action_obj);
89
90    if (action_obj->description)
91      g_free(action_obj->description);
92
93    g_free(action_obj);
94 }
95
96 /**
97  * @brief Finalizes function for GObject
98  *
99  * @param object GObject(EailActionWidget) instance to be freed
100  */
101 static void
102 eail_action_widget_finalize(GObject *object)
103 {
104    EailActionWidget *widget = NULL;
105    const Eina_List *l = NULL;
106    EailActionObj *action_obj = NULL;
107
108    widget = EAIL_ACTION_WIDGET(object);
109    if (!widget)
110      {
111         ERR("could not get action widget from gobject");
112         return;
113      }
114
115    EINA_LIST_FOREACH(widget->action_objs, l, action_obj)
116      eail_action_obj_free(action_obj);
117
118    eina_list_free(widget->action_objs);
119
120    G_OBJECT_CLASS(eail_action_widget_parent_class)->finalize(object);
121 }
122
123 /**
124  * @brief Initiates function for GObject
125  *
126  * @param klass EailActionWidgetClass instance to be filled
127  */
128 static void
129 eail_action_widget_class_init(EailActionWidgetClass *klass)
130 {
131    AtkObjectClass *atk_class = ATK_OBJECT_CLASS(klass);
132    GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
133    atk_class->initialize = eail_action_widget_initialize;
134    gobject_class->finalize = eail_action_widget_finalize;
135 }
136
137 /**
138  * @param action_widget ActionWidget instance that holds actions
139  * @param action_name action name
140  * @param keybinding keybinding
141  * @param action_cb callback for action, launched when action is triggered
142  */
143 void
144 eail_action_widget_action_append(EailActionWidget *action_widget,
145                                  const gchar *action_name,
146                                  const gchar *keybinding,
147                                  Eail_Do_Action_Cb action_cb)
148 {
149    if (!action_widget)
150      {
151          ERR("action widget should NOT be NULL");
152          return;
153      }
154
155    EailActionObj *action_def_obj = g_new0(EailActionObj, 1);
156
157    action_def_obj->name = action_name;
158    action_def_obj->keybinding = keybinding;
159    action_def_obj->action = action_cb;
160
161    action_widget->action_objs = eina_list_append
162                               (action_widget->action_objs, action_def_obj);
163
164 }
165
166 /**
167  * @brief Returns the number of implemented ATK actions.
168  *
169  * Implementation of AtkActionIface get_n_actions callback.
170  *
171  * @param action AtkAction instance
172  *
173  * @returns integer containing the number of implemented ATK actions
174  */
175 static int
176 eail_action_widget_n_actions_get(AtkAction *action)
177 {
178    EailActionWidget *widget =  EAIL_ACTION_WIDGET(action);
179    if (!widget)
180      {
181         ERR("Could not get action widget from action");
182         return 0;
183      }
184
185    return eina_list_count(widget->action_objs);
186 }
187
188 /**
189  * @brief Returns EailActionObj of an action with the specified index
190  *
191  * @param action AtkAction instance
192  * @param i index (number) of action
193  *
194  * @returns EailActionObj representing the specified action
195  */
196 static EailActionObj *
197 eail_get_action_obj_i(AtkAction *action,
198                       int i)
199 {
200    EailActionWidget *widget =  EAIL_ACTION_WIDGET(action);
201    if (!widget)
202      {
203         ERR("Could not get action widget from action");
204         return NULL;
205      }
206
207
208    if (i >= eina_list_count(widget->action_objs))
209      {
210         DBG("Passed index value %d is invalid", i);
211         return NULL;
212      }
213
214    EailActionObj *actionObj = eina_list_nth(widget->action_objs, i);
215
216    return actionObj;
217 }
218
219 /**
220  * @brief Returns EailActionObj of an action with the specified index
221  *
222  * @param action AtkAction instance
223  * @param i index (number) of action
224  *
225  * @returns string representing the name of the specified action
226  */
227 static const gchar*
228 eail_action_widget_action_name_get(AtkAction *action,
229                                    int i)
230 {
231    EailActionObj *actionObj = eail_get_action_obj_i(action, i);
232    if(!actionObj) return NULL;
233
234    return actionObj->name;
235 }
236
237 /**
238  * @brief Launches the action with the specified index
239  *
240  * @param action AtkAction instance
241  * @param i index (number) of action
242  *
243  * @returns TRUE if action was successfully launched, FALSE otherwise
244  */
245 static gboolean
246 eail_action_widget_do_action(AtkAction *action,
247                              int i)
248 {
249    EailActionObj *actionObj = eail_get_action_obj_i(action, i);
250    if(!actionObj) return FALSE;
251
252    return (actionObj->action)(action, NULL);
253 }
254
255 /**
256  * @brief Gets the description of an action with the specified index
257  *
258  * Implementation of AtkActionIface get_description callback.
259  *
260  * @param action AtkAction instance
261  * @param i index (number) of action
262  *
263  * @returns string representing the description of the specified action
264  */
265 static const gchar*
266 eail_action_widget_description_get(AtkAction *action,
267                                    int i)
268 {
269    EailActionObj *actionObj = eail_get_action_obj_i(action, i);
270    if(!actionObj) return NULL;
271
272    return actionObj->description;
273 }
274
275 /**
276  * @brief Sets description for action with given index
277  *
278  * Implementation of AtkActionIface set_description callback.
279  *
280  * @param action AtkAction instance
281  * @param i index (number) of action
282  * @param description description to set
283  *
284  * @returns TRUE if update operation was successful, FALSE otherwise
285  */
286 static gboolean
287 eail_action_widget_description_set(AtkAction *action,
288                                    int i,
289                                    const char *description)
290 {
291    EailActionObj *actionObj = eail_get_action_obj_i(action, i);
292    if(!actionObj) return FALSE;
293
294    if (actionObj->description)
295      g_free(actionObj->description);
296
297    actionObj->description = g_strdup(description);
298    return TRUE;
299 }
300
301 /**
302  * \brief Initializes AtkAction interface
303  *
304  * Function called upon instance creation. It initializes AtkAction interface
305  * implementation i.e hooks method pointers in the interface structure
306  * to the implementing class's implementation.
307  *
308  * @param iface AtkActionIface instance to be filled
309  */
310 static void
311 atk_action_interface_init(AtkActionIface *iface)
312 {
313    if(!iface) return;
314
315    iface->do_action       = eail_action_widget_do_action;
316    iface->get_n_actions   = eail_action_widget_n_actions_get;
317    iface->get_name        = eail_action_widget_action_name_get;
318    iface->get_description = eail_action_widget_description_get;
319    iface->set_description = eail_action_widget_description_set;
320 }