Merge "custom eail widget implementation" into tizen
[platform/core/uifw/eail.git] / eail / eail_image.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_image.c
22  * @brief EailImage implementation
23  */
24
25 #include <Elementary.h>
26 #include "eail_image.h"
27
28 /**
29  * @brief 'click' action name
30  */
31 #define EAIL_IMAGE_ACTION_CLICK "click"
32
33 static void atk_image_interface_init(AtkImageIface *iface);
34
35 /**
36  * @brief EailImage type definition
37  */
38 G_DEFINE_TYPE_WITH_CODE(EailImage,
39                         eail_image,
40                         EAIL_TYPE_ACTION_WIDGET,
41                         G_IMPLEMENT_INTERFACE(ATK_TYPE_IMAGE,
42                                               atk_image_interface_init));
43
44 /**
45  * @brief Callback for "click" action on elm_image object
46  *
47  * @param action AtkAction instance
48  * @param data user data passed to callback
49  *
50  * @returns TRUE on success, FALSE otherwise
51  */
52 static gboolean
53 _eail_image_action_click(AtkAction *action, void *data)
54 {
55    Evas_Object *widget;
56
57    g_return_val_if_fail(EAIL_IS_IMAGE(action), FALSE);
58    widget = eail_widget_get_widget(EAIL_WIDGET(action));
59    if (!widget) return FALSE;
60
61    if ((elm_object_disabled_get(widget)) || (!evas_object_visible_get(widget)))
62      return FALSE;
63
64     evas_object_smart_callback_call(widget, "clicked", NULL);
65
66     return TRUE;
67 }
68
69 /*
70  * Implementation of the *AtkObject* interface
71  */
72
73 /**
74  *
75  * @brief Initializes AtkObject instance
76  *
77  * @param obj AtkObject instance
78  * @param data user data passed to initialization
79  */
80 static void
81 eail_image_initialize(AtkObject *obj, gpointer data)
82 {
83    ATK_OBJECT_CLASS(eail_image_parent_class)->initialize(obj, data);
84
85    obj->role = ATK_ROLE_IMAGE;
86
87    eail_action_widget_action_append(EAIL_ACTION_WIDGET(obj),
88                                     EAIL_IMAGE_ACTION_CLICK,
89                                     NULL,
90                                     _eail_image_action_click);
91 }
92
93 /**
94  * @brief Finalizes EailImage instance
95  *
96  * @param object GObject instance
97  */
98 static void
99 eail_image_finalize(GObject *object)
100 {
101    EailImage *obj;
102
103    obj = EAIL_IMAGE(object);
104    if (obj->description) free(obj->description);
105
106    G_OBJECT_CLASS(eail_image_parent_class)->finalize(object);
107 }
108
109 /**
110  * @brief Initiates EailImage instance
111  *
112  * @param image EalImage instance
113  */
114 static void
115 eail_image_init(EailImage *image)
116 {
117    image->description = NULL;
118 }
119
120 /**
121  * @brief Gets a reference to the state set of the accessible
122  *
123  * The caller must unreference it when it is no longer needed.
124  *
125  * Implementation of ref_state_set from AtkObject.
126  *
127  * @param obj AtkObject instance
128  *
129  * @returns AtkStateSet representing the state set of the accessible
130  */
131 static AtkStateSet *
132 eail_image_ref_state_set(AtkObject *obj)
133 {
134    AtkStateSet *state_set;
135    Evas_Object *widget = eail_widget_get_widget(EAIL_WIDGET(obj));
136    Eina_Bool resizable_up, resizable_down;
137
138    if (!widget)
139      {
140         return NULL;
141      }
142
143    state_set = ATK_OBJECT_CLASS(eail_image_parent_class)->ref_state_set(obj);
144    if (!evas_object_smart_type_check(widget, "elm_image"))
145      return state_set;
146
147    if (elm_image_animated_get(widget))
148      {
149         atk_state_set_add_state(state_set, ATK_STATE_ANIMATED);
150      }
151
152    elm_image_resizable_get(widget, &resizable_up, &resizable_down);
153    if ((resizable_up) || (resizable_down))
154      {
155         atk_state_set_add_state(state_set, ATK_STATE_RESIZABLE);
156      }
157
158    return state_set;
159 }
160
161 /**
162  * @brief EailImage class initialization
163  *
164  * @param klass EailImageClass instance
165  */
166 static void
167 eail_image_class_init(EailImageClass *klass)
168 {
169    AtkObjectClass *atk_class = ATK_OBJECT_CLASS(klass);
170    GObjectClass *g_object_class = G_OBJECT_CLASS(klass);
171
172    atk_class->initialize = eail_image_initialize;
173    atk_class->ref_state_set = eail_image_ref_state_set;
174
175    g_object_class->finalize = eail_image_finalize;
176 }
177
178 /*
179  * Implementation of the *AtkImage* interface
180  */
181
182 /**
183  * @brief Gets the position of the image in the form of a point specifying the images top-left corner
184  *
185  * Implementation of get_image_postition from AtkImage interface.
186  *
187  * @param image AtkImage instance
188  * @param [out] x x coordinate or -1 if value cannot be obtained
189  * @param [out] y y coordinate or -1 if value cannot be obtained
190  * @param coord_type specifies whether the coordinates are relative to the screen or to the components top level window
191  */
192 static void
193 eail_image_position_get(AtkImage *image,
194                         gint *x,
195                         gint *y,
196                         AtkCoordType coord_type)
197 {
198    atk_component_get_position(ATK_COMPONENT(image), x, y, coord_type);
199 }
200
201 /**
202  * @brief Gets the width and height in pixels for the specified image
203  *
204  * The values of width and height are returned as -1 if the values
205  * cannot be obtained (for instance, if the object is not onscreen).
206  *
207  * Implementation of get_image_size from AtkImage interface.
208  *
209  * @param image EailImage instance
210  * @param [out] width width of image or -1 if value cannot be obtained
211  * @param [out] height height of image or -1 if value cannot be obtained
212  */
213 static void
214 eail_image_size_get(AtkImage *image, gint *width, gint *height)
215 {
216    Evas_Object *widget;
217
218    widget = eail_widget_get_widget(EAIL_WIDGET(image));
219    if (!widget)
220      {
221         *width = -1;
222         *height = -1;
223         return;
224      }
225
226    elm_image_object_size_get(widget, width, height);
227 }
228
229 /**
230  * @brief Gets a textual description of the image
231  *
232  * Implementation of get_image_description from AtkImage interface.
233  *
234  * @param image AtkImage instance
235  *
236  * @returns string representing the image description
237  */
238 static const gchar *
239 eail_image_description_get(AtkImage *image)
240 {
241    EailImage *obj = EAIL_IMAGE(image);
242    return obj->description;
243 }
244
245 /**
246  * @brief Sets the textual description for the image
247  *
248  * Implementation of set_image_description from AtkImage interface.
249  *
250  * @param image AtkImage instance
251  * @param description image's description to set
252  *
253  * @returns TRUE on success
254  */
255 static gboolean
256 eail_image_description_set(AtkImage *image, const gchar *description)
257 {
258    EailImage *obj = EAIL_IMAGE(image);
259
260    if (obj->description)
261      free(obj->description);
262
263    obj->description = strdup(description);
264
265    return TRUE;
266 }
267
268 /**
269  * @brief Gets image's locale (LC_MESSAGES variable)
270  *
271  * @param image AtkImage instance
272  * @return string corresponding to the POSIX LC_MESSAGES
273  * locale used by the image description, or NULL if
274  * the image does not specify a locale
275  *
276  */
277 const gchar *
278 eail_image_get_image_locale(AtkImage *image)
279 {
280     return setlocale(LC_MESSAGES, NULL);
281 }
282
283 /**
284  * @brief Initializes AtkImage interface
285  *
286  * @param iface AtkImageIface instance
287  */
288 static void
289 atk_image_interface_init(AtkImageIface *iface)
290 {
291    g_return_if_fail(iface != NULL);
292
293    iface->get_image_position    = eail_image_position_get;
294    iface->get_image_size        = eail_image_size_get;
295    iface->get_image_description = eail_image_description_get;
296    iface->set_image_description = eail_image_description_set;
297    iface->get_image_locale      = eail_image_get_image_locale;
298 }