6b532b2ad667a032089aef42166b7ac2fee88484
[platform/core/uifw/eail.git] / eail / eail / eail_slideshow.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_slideshow.c
22  * @brief EailSlideshow implementation
23  */
24
25 #include <Elementary.h>
26
27 #include "eail_slideshow.h"
28 #include "eail_factory.h"
29 #include "eail_priv.h"
30
31 /**
32  * @brief Default timeout in seconds
33  */
34 #define SLIDESHOW_DEFAULT_TIMEOUT 3.0
35
36 static void atk_selection_interface_init(AtkSelectionIface *iface);
37 static void atk_action_interface_init(AtkActionIface *iface);
38
39 /**
40  * @brief Define GObject type
41  */
42 G_DEFINE_TYPE_WITH_CODE(EailSlideshow, eail_slideshow, EAIL_TYPE_WIDGET,
43                         G_IMPLEMENT_INTERFACE(ATK_TYPE_SELECTION,
44                                               atk_selection_interface_init)
45                         G_IMPLEMENT_INTERFACE(ATK_TYPE_ACTION,
46                                               atk_action_interface_init));
47
48 /**
49  * @brief Implementation of ref_child from AtkObject interface
50  *
51  * @param obj EailSlideshow instance
52  * @param i index of a child object
53  *
54  * @returns child object
55  */
56 static AtkObject*
57 eail_slideshow_ref_child(AtkObject *obj, gint i)
58 {
59    Evas_Object *widget, *child_widget;
60    Elm_Object_Item *it;
61
62    g_return_val_if_fail(EAIL_IS_SLIDESHOW(obj), NULL);
63
64    widget = eail_widget_get_widget(EAIL_WIDGET(obj));
65    if (!widget) return NULL;
66
67    it = elm_slideshow_item_nth_get(widget, i);
68    if (!it) return NULL;
69
70    child_widget = elm_slideshow_item_object_get(it);
71    if (!child_widget)
72      {
73         WRN("Given index %d is beyond realized (cached) views. Returning NULL",
74             i);
75         return NULL;
76      }
77
78    return eail_factory_get_accessible(child_widget);
79 }
80
81 /**
82  * @brief Implementation of get_n_children from AtkObject interface
83  *
84  * @param obj EailSlideshow instance
85  * @returns number of widget childs
86  */
87 static gint
88 eail_slideshow_n_children_get(AtkObject *obj)
89 {
90    Evas_Object *widget;
91    gint items_count;
92
93    g_return_val_if_fail(EAIL_IS_SLIDESHOW(obj), 0);
94
95    widget = eail_widget_get_widget(EAIL_WIDGET(obj));
96    if (!widget) return 0;
97    /*the real number of items stored in slideshow widget is returned by
98      elm_slideshow_count_get. However we will not be able to return all items
99      widget since only those stored in cache are created.*/
100    items_count = elm_slideshow_count_get(widget);
101    return items_count;
102 }
103
104 /**
105  * @brief Initialize EailSlideshow as a AtkObject
106  *
107  * @param obj EailSlideshow instance
108  * @param data user data passed to initialization
109  */
110 static void
111 eail_slideshow_initialize(AtkObject *obj, gpointer data)
112 {
113    ATK_OBJECT_CLASS(eail_slideshow_parent_class)->initialize(obj, data);
114    obj->role = ATK_ROLE_DOCUMENT_PRESENTATION;
115 }
116
117 /**
118  * @brief EailSlideshow object initialization
119  *
120  * @param slideshow EailSlideshow instance
121  */
122 static void
123 eail_slideshow_init(EailSlideshow *slideshow)
124 {
125    slideshow->next_description = NULL;
126    slideshow->previous_description = NULL;
127    slideshow->stop_description = NULL;
128    slideshow->start_description = NULL;
129 }
130
131 /**
132  * @brief Destructor of EailSlideshow object
133  *
134  * @param object EailSlideshow instance
135  */
136 static void
137 eail_slideshow_finalize(GObject *object)
138 {
139    EailSlideshow *slideshow = EAIL_SLIDESHOW(object);
140    if (slideshow->next_description) free(slideshow->next_description);
141    if (slideshow->previous_description) free(slideshow->previous_description);
142    if (slideshow->stop_description) free(slideshow->stop_description);
143    if (slideshow->start_description) free(slideshow->start_description);
144
145    G_OBJECT_CLASS(eail_slideshow_parent_class)->finalize(object);
146
147 }
148
149 /**
150  * @brief EailSlideshow class initialization
151  *
152  * @param klass EailSlideshowClass object
153  */
154 static void
155 eail_slideshow_class_init(EailSlideshowClass *klass)
156 {
157    AtkObjectClass *atk_class = ATK_OBJECT_CLASS(klass);
158    GObjectClass *g_object_class = G_OBJECT_CLASS(klass);
159
160    atk_class->initialize = eail_slideshow_initialize;
161    atk_class->get_n_children = eail_slideshow_n_children_get;
162    atk_class->ref_child = eail_slideshow_ref_child;
163
164    g_object_class->finalize = eail_slideshow_finalize;
165 }
166
167 /**
168  * @brief Implementation of selection_count from AtkSelection interface
169  *
170  * @param selection EailSlideshow instance
171  *
172  * @returns number of actions
173  */
174 static gint
175 eail_slideshow_selection_count(AtkSelection *selection)
176 {
177    g_return_val_if_fail(EAIL_IS_SLIDESHOW(selection), 0);
178
179    return 1;
180 }
181
182 /**
183  * @brief Implementation of add_selection from AtkSelection interface
184  *
185  * @param selection EailSlideshow instance
186  * @param i index of object to select
187  *
188  * @returns TRUE on success FALSE otherwise
189  */
190 static gboolean
191 eail_slideshow_add_selection(AtkSelection *selection, gint i)
192 {
193    Evas_Object *widget;
194    Elm_Object_Item *it;
195
196    g_return_val_if_fail(EAIL_IS_SLIDESHOW(selection), FALSE);
197
198    widget = eail_widget_get_widget(EAIL_WIDGET(selection));
199    if (!widget) return FALSE;
200
201    it = elm_slideshow_item_nth_get(widget, i);
202    if (!it) return FALSE;
203
204    elm_slideshow_item_show(it);
205
206    return TRUE;
207 }
208
209 /**
210  * @brief Implementation ref_selecton from AtkSelection
211  *
212  * @param selection EailSlideshow instance
213  * @param i index of selection
214  *
215  * @returns selected AtkObject
216  */
217 static AtkObject*
218 eail_slideshow_ref_selection(AtkSelection *selection, gint i)
219 {
220    Evas_Object *widget, *it_widget;
221    Elm_Object_Item *it;
222
223    g_return_val_if_fail(EAIL_IS_SLIDESHOW(selection), NULL);
224    g_return_val_if_fail(i == 0, NULL);
225
226    widget = eail_widget_get_widget(EAIL_WIDGET(selection));
227    it = elm_slideshow_item_current_get(widget);
228
229    it_widget = elm_slideshow_item_object_get(it);
230
231    return eail_factory_get_accessible(it_widget);
232 }
233
234 /**
235  * @brief Implementation of is_child_selected from AtkSelection
236  *
237  * @param selection EailSlideshow instace
238  * @param i index of selection
239  *
240  * @return TRUE if object is selected FALSE otherwise
241  */
242 static gboolean
243 eail_slideshow_is_child_selected(AtkSelection *selection, gint i)
244 {
245    Evas_Object *widget;
246    Elm_Object_Item *it, *current;
247
248    g_return_val_if_fail(EAIL_IS_SLIDESHOW(selection), FALSE);
249
250    widget = eail_widget_get_widget(EAIL_WIDGET(selection));
251    if (!widget) return FALSE;
252
253    current = elm_slideshow_item_current_get(widget);
254    it = elm_slideshow_item_nth_get(widget, i);
255
256    return (it == current);
257 }
258
259 /**
260  * @brief Initialization of AtkSelection interface
261  *
262  * Function called upon instance creation. It initializes AtkValue interface
263  * implementation i.e hooks method pointers in the interface structure
264  * to the implementing class's implementation.
265  *
266  * @param iface an AtkObject than implements AtkSelectionInterface
267  */
268 static void atk_selection_interface_init(AtkSelectionIface *iface)
269 {
270    g_return_if_fail(iface != NULL);
271
272    iface->add_selection = eail_slideshow_add_selection;
273    iface->ref_selection = eail_slideshow_ref_selection;
274    iface->get_selection_count = eail_slideshow_selection_count;
275    iface->is_child_selected = eail_slideshow_is_child_selected;
276 }
277
278 /**
279  * @brief Implementation of get_n_action from AtkAction interface
280  *
281  * @param action EailSlideshow instance
282  * @returns number of implemented actions
283  */
284 static gint
285 eail_slideshow_n_actions_get(AtkAction *action)
286 {
287    g_return_val_if_fail(EAIL_IS_SLIDESHOW(action), 0);
288
289    return 4;
290 }
291
292 /**
293  * @brief Implementation of get_action_name from AtkAction interface
294  *
295  * @param action EailSlideshow instance
296  * @param i action index
297  *
298  * @returns acton name
299  */
300 static const gchar*
301 eail_slideshow_action_name_get(AtkAction *action, int i)
302 {
303    const gchar *action_name;
304    g_return_val_if_fail(EAIL_IS_SLIDESHOW(action), NULL);
305    switch (i)
306      {
307       case 0:
308          /*advance to next image*/
309          action_name = "next";
310          break;
311       case 1:
312          /*advance to previous image*/
313          action_name = "previous";
314          break;
315       case 2:
316          /*stop the slideshow*/
317          action_name = "stop";
318          break;
319       case 3:
320          /*start the slideshow*/
321          action_name = "start";
322          break;
323       default:
324          action_name = NULL;
325          break;
326      }
327
328    return action_name;
329 }
330
331 /**
332  * @brief Compares two doubles
333  * @param A first number
334  * @param B second number
335  * @param max_ulps number of doubles between A and B
336  * @returns TRUE if A == B, FALSE otherwise
337  */
338 static gboolean
339 _double_cmp(double A, double B, gint max_ulps)
340 {
341    union {
342         double d;
343         gint64 i;
344    }f1, f2;
345    gint64 diff;
346
347    f1.d = A;
348    f2.d = B;
349
350    g_assert(max_ulps > 0 && max_ulps < 4*1024*1024);
351
352    if (f1.i < 0) f1.i = 0x80000000 - f1.i;
353    if (f2.i < 0) f1.i = 0x80000000 - f2.i;
354
355    diff = abs(f1.i - f2.i);
356    if (diff <= max_ulps)
357      return TRUE;
358
359    return FALSE;
360 }
361
362 /**
363  * @brief Implementation of do action from AtkAction interface
364  *
365  * @param action EailSlideshow instance
366  * @param i action index
367  *
368  * @returns TRUE on success, FALSE otherwise
369  */
370 static gboolean
371 eail_slideshow_do_action(AtkAction *action, gint i)
372 {
373    Evas_Object *widget;
374    gboolean result;
375    double slideshow_timeout;
376
377    g_return_val_if_fail(EAIL_IS_SLIDESHOW(action), FALSE);
378
379    widget = eail_widget_get_widget(EAIL_WIDGET(action));
380    if (!widget) return FALSE;
381
382    if ((elm_object_disabled_get(widget)) || (!evas_object_visible_get(widget)))
383      return FALSE;
384
385    switch (i)
386      {
387        case 0:
388            elm_slideshow_next(widget);
389            result = TRUE;
390            break;
391        case 1:
392            elm_slideshow_previous(widget);
393            result = TRUE;
394            break;
395        case 2:
396            elm_slideshow_timeout_set(widget, 0.0);
397            result = TRUE;
398            break;
399        case 3:
400            slideshow_timeout = elm_slideshow_timeout_get(widget);
401            if (_double_cmp(slideshow_timeout, 0.0, 1))
402              {
403                 result = TRUE;
404                 elm_slideshow_timeout_set(widget, SLIDESHOW_DEFAULT_TIMEOUT);
405                 break;
406              }
407            result = FALSE;
408            break;
409        default:
410            result = FALSE;
411            break;
412      }
413
414    return result;
415 }
416
417 /**
418  * @brief Implementation of get_description from AtkAction interface
419  *
420  * @param action EailSlideshow instance
421  * @param i action index
422  *
423  * @returns action description
424  */
425 static const gchar *
426 eail_slidshow_description_get(AtkAction *action, gint i)
427 {
428    const gchar *action_description;
429    EailSlideshow *slideshow;
430
431    g_return_val_if_fail(EAIL_IS_SLIDESHOW(action), NULL);
432
433    slideshow = EAIL_SLIDESHOW(action);
434    switch (i)
435      {
436        case 0:
437            action_description = slideshow->next_description;
438            break;
439        case 1:
440            action_description = slideshow->previous_description;
441            break;
442        case 2:
443            action_description = slideshow->stop_description;
444            break;
445        case 3:
446            action_description = slideshow->start_description;
447            break;
448        default:
449            action_description = NULL;
450            break;
451      }
452    return action_description;
453 }
454
455 /**
456  * @brief Implementation of set_description from AtkAction interface
457  *
458  * @param action EailSlideshow instance
459  * @param i action index
460  * @param description action description to set
461  *
462  * @returns TRUE on success, FALSE otherwise
463  */
464 static gboolean
465 eail_slideshow_description_set(AtkAction *action, gint i,
466                                const char *description)
467 {
468    EailSlideshow *slideshow;
469    gchar **value;
470
471    g_return_val_if_fail(EAIL_IS_SLIDESHOW(action), FALSE);
472
473    slideshow = EAIL_SLIDESHOW(action);
474    switch (i)
475      {
476        case 0:
477            value = &slideshow->next_description;
478            break;
479        case 1:
480            value = &slideshow->previous_description;
481            break;
482        case 2:
483            value = &slideshow->stop_description;
484            break;
485        case 3:
486            value = &slideshow->start_description;
487            break;
488        default:
489            value = NULL;
490            break;
491      }
492    if (value)
493      {
494         free(*value);
495         *value = g_strdup(description);
496         return TRUE;
497      }
498    return FALSE;
499 }
500
501 /**
502  * @brief AtkAction interface initialization
503  *
504  * @param iface EailSlideshow object
505  */
506 static void
507 atk_action_interface_init(AtkActionIface *iface)
508 {
509    g_return_if_fail(iface != NULL);
510    iface->do_action = eail_slideshow_do_action;
511    iface->get_n_actions = eail_slideshow_n_actions_get;
512    iface->get_description = eail_slidshow_description_get;
513    iface->set_description = eail_slideshow_description_set;
514    iface->get_name = eail_slideshow_action_name_get;
515    /*unsupported*/
516    /*iface->get_localized_name;*/
517    /*iface->get_keybinding;*/
518 }