Merge remote-tracking branch 'remotes/origin/upstream'
[framework/uifw/elementary.git] / src / lib / elm_thumb.c
1 #include <Elementary.h>
2 #include "elm_priv.h"
3 #include <assert.h>
4
5 typedef struct _Widget_Data Widget_Data;
6
7 struct _Widget_Data
8 {
9    Evas_Object *self;
10    Evas_Object *frame;
11    Evas_Object *view;
12    const char *file;
13    const char *key;
14    struct
15      {
16         const char *file;
17         const char *key;
18 #ifdef HAVE_ELEMENTARY_ETHUMB
19         const char *thumb_path;
20         const char *thumb_key;
21         Ethumb_Client_Async *request;
22
23         Ethumb_Thumb_Format format;
24
25         Eina_Bool retry : 1;
26 #endif
27      } thumb;
28    Ecore_Event_Handler *eeh;
29    Elm_Thumb_Animation_Setting anim_setting;
30    Eina_Bool on_hold : 1;
31    Eina_Bool is_video : 1;
32    Eina_Bool was_video : 1;
33    Eina_Bool edit : 1;
34 };
35
36 static const char *widtype = NULL;
37
38 static const char SIG_CLICKED[] = "clicked";
39 static const char SIG_CLICKED_DOUBLE[] = "clicked,double";
40 static const char SIG_GENERATE_ERROR[] = "generate,error";
41 static const char SIG_GENERATE_START[] = "generate,start";
42 static const char SIG_GENERATE_STOP[] = "generate,stop";
43 static const char SIG_LOAD_ERROR[] = "load,error";
44 static const char SIG_PRESS[] = "press";
45
46 static const Evas_Smart_Cb_Description _signals[] =
47 {
48      {SIG_CLICKED, ""},
49      {SIG_CLICKED_DOUBLE, ""},
50      {SIG_GENERATE_ERROR, ""},
51      {SIG_GENERATE_START, ""},
52      {SIG_GENERATE_STOP, ""},
53      {SIG_LOAD_ERROR, ""},
54      {SIG_PRESS, ""},
55      {NULL, NULL}
56 };
57
58 #define EDJE_SIGNAL_GENERATE_START "elm,thumb,generate,start"
59 #define EDJE_SIGNAL_GENERATE_STOP "elm,thumb,generate,stop"
60 #define EDJE_SIGNAL_GENERATE_ERROR "elm,thumb,generate,error"
61 #define EDJE_SIGNAL_LOAD_ERROR "elm,thumb,load,error"
62 #define EDJE_SIGNAL_PULSE_START "elm,state,pulse,start"
63 #define EDJE_SIGNAL_PULSE_STOP "elm,state,pulse,stop"
64
65 struct _Ethumb_Client *_elm_ethumb_client = NULL;
66 Eina_Bool _elm_ethumb_connected = EINA_FALSE;
67 #ifdef HAVE_ELEMENTARY_ETHUMB
68 static Eina_List *retry = NULL;
69 static int pending_request = 0;
70 #endif
71
72 EAPI int ELM_ECORE_EVENT_ETHUMB_CONNECT = 0;
73
74 static void
75 _del_hook(Evas_Object *obj)
76 {
77    Widget_Data *wd = elm_widget_data_get(obj);
78
79 #ifdef HAVE_ELEMENTARY_ETHUMB
80    if (wd->thumb.request)
81      {
82        ethumb_client_thumb_async_cancel(_elm_ethumb_client, wd->thumb.request);
83        wd->thumb.request = NULL;
84      }
85    if (wd->thumb.retry)
86      {
87         retry = eina_list_remove(retry, wd);
88         wd->thumb.retry = EINA_FALSE;
89      }
90
91    eina_stringshare_del(wd->thumb.thumb_path);
92    eina_stringshare_del(wd->thumb.thumb_key);
93 #endif
94
95    eina_stringshare_del(wd->file);
96    eina_stringshare_del(wd->key);
97    if (wd->eeh) ecore_event_handler_del(wd->eeh);
98    free(wd);
99 }
100
101 static void
102 _theme_hook(Evas_Object *obj)
103 {
104    Widget_Data *wd = elm_widget_data_get(obj);
105    _elm_theme_object_set(obj, wd->frame, "thumb", "base",
106                          elm_widget_style_get(obj));
107 }
108
109 #ifdef HAVE_ELEMENTARY_ETHUMB
110 static void
111 _mouse_down_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
112 {
113    Widget_Data *wd = data;
114    Evas_Event_Mouse_Down *ev = event_info;
115
116    if (ev->button != 1)
117      return;
118    if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
119      wd->on_hold = EINA_TRUE;
120    else
121      wd->on_hold = EINA_FALSE;
122    if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
123      evas_object_smart_callback_call(wd->self, SIG_CLICKED_DOUBLE, NULL);
124    else
125      evas_object_smart_callback_call(wd->self, SIG_PRESS, NULL);
126 }
127
128 static void
129 _mouse_up_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
130 {
131    Widget_Data *wd = data;
132    Evas_Event_Mouse_Up *ev = event_info;
133
134    if (ev->button != 1)
135      return;
136    if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
137      wd->on_hold = EINA_TRUE;
138    else
139      wd->on_hold = EINA_FALSE;
140    if (!wd->on_hold)
141      evas_object_smart_callback_call(wd->self, SIG_CLICKED, NULL);
142    wd->on_hold = EINA_FALSE;
143 }
144
145 static void
146 _thumb_ready(Widget_Data *wd, const char *thumb_path, const char *thumb_key)
147 {
148    Evas_Coord mw, mh;
149    Evas_Coord aw, ah;
150
151    evas_object_image_size_get(wd->view, &aw, &ah);
152    evas_object_size_hint_aspect_set(wd->view,
153                                     EVAS_ASPECT_CONTROL_BOTH,
154                                     aw, ah);
155    edje_object_part_swallow(wd->frame, "elm.swallow.content", wd->view);
156    edje_object_size_min_get(wd->frame, &mw, &mh);
157    edje_object_size_min_restricted_calc(wd->frame, &mw, &mh, mw, mh);
158    evas_object_size_hint_min_set(wd->self, mw, mh);
159    eina_stringshare_replace(&(wd->thumb.file), thumb_path);
160    eina_stringshare_replace(&(wd->thumb.key), thumb_key);
161    edje_object_signal_emit(wd->frame, EDJE_SIGNAL_PULSE_STOP, "elm");
162    edje_object_signal_emit(wd->frame, EDJE_SIGNAL_GENERATE_STOP, "elm");
163    evas_object_smart_callback_call(wd->self, SIG_GENERATE_STOP, NULL);
164 }
165
166 static void
167 _thumb_loaded(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
168 {
169    Widget_Data *wd = data;
170    const char *thumb_path;
171    const char *thumb_key;
172
173    evas_object_image_file_get(wd->view, &thumb_path, &thumb_key);
174
175    _thumb_ready(wd, thumb_path, thumb_key);
176 }
177
178 /* As we do use stat to check if a thumbnail is available, it's possible
179    that we end up accessing before the file is completly written on disk.
180    By retrying each time a thumbnail is finished we should be fine or not.
181 */
182 static Eina_Bool
183 _retry_thumb(Widget_Data *wd)
184 {
185    int r;
186
187    if ((wd->is_video) && (wd->thumb.format == ETHUMB_THUMB_EET))
188      {
189         edje_object_file_set(wd->view, NULL, NULL);
190         if (!edje_object_file_set(wd->view,
191                                   wd->thumb.thumb_path,
192                                   "movie/thumb"))
193           {
194              if (pending_request == 0)
195                ERR("could not set file=%s key=%s for %s",
196                    wd->thumb.thumb_path,
197                    wd->thumb.thumb_key,
198                    wd->file);
199              goto view_err;
200           }
201      }
202    else
203      {
204         evas_object_image_file_set(wd->view, NULL, NULL);
205         evas_object_image_file_set(wd->view,
206                                    wd->thumb.thumb_path,
207                                    wd->thumb.thumb_key);
208         r = evas_object_image_load_error_get(wd->view);
209         if (r != EVAS_LOAD_ERROR_NONE)
210           {
211              if (pending_request == 0)
212                ERR("%s: %s", wd->thumb.thumb_path, evas_load_error_str(r));
213              goto view_err;
214           }
215
216         evas_object_event_callback_add(wd->view,
217                                        EVAS_CALLBACK_IMAGE_PRELOADED,
218                                        _thumb_loaded, wd);
219         evas_object_image_preload(wd->view, EINA_TRUE);
220         return EINA_TRUE;
221      }
222
223    _thumb_ready(wd, wd->thumb.thumb_path, wd->thumb.thumb_key);
224
225    eina_stringshare_del(wd->thumb.thumb_path);
226    wd->thumb.thumb_path = NULL;
227
228    eina_stringshare_del(wd->thumb.thumb_key);
229    wd->thumb.thumb_key = NULL;
230
231    return EINA_TRUE;
232
233  view_err:
234    return EINA_FALSE;
235 }
236
237 static void
238 _finished_thumb(Widget_Data *wd,
239                 const char *thumb_path,
240                 const char *thumb_key)
241 {
242    Eina_List *l, *ll;
243    Evas *evas;
244    int r;
245
246    evas = evas_object_evas_get(wd->self);
247    if ((wd->view) && (wd->is_video ^ wd->was_video))
248      {
249         evas_object_del(wd->view);
250         wd->view = NULL;
251      }
252    wd->was_video = wd->is_video;
253
254    if ((wd->is_video) &&
255        (ethumb_client_format_get(_elm_ethumb_client) == ETHUMB_THUMB_EET))
256      {
257         if (!wd->view)
258           {
259              wd->view = edje_object_add(evas);
260              if (!wd->view)
261                {
262                   ERR("could not create edje object");
263                   goto err;
264                }
265              elm_widget_sub_object_add(wd->self, wd->view);
266           }
267
268         if (!edje_object_file_set(wd->view, thumb_path, thumb_key))
269           {
270              wd->thumb.thumb_path = eina_stringshare_ref(thumb_path);
271              wd->thumb.thumb_key = eina_stringshare_ref(thumb_key);
272              wd->thumb.format = ethumb_client_format_get(_elm_ethumb_client);
273              wd->thumb.retry = EINA_TRUE;
274
275              retry = eina_list_append(retry, wd);
276              return ;
277           }
278      }
279    else
280      {
281         if (!wd->view)
282           {
283              wd->view = evas_object_image_filled_add(evas);
284              if (!wd->view)
285                {
286                   ERR("could not create image object");
287                   goto err;
288                }
289              evas_object_event_callback_add(wd->view,
290                                             EVAS_CALLBACK_IMAGE_PRELOADED,
291                                             _thumb_loaded, wd);
292              elm_widget_sub_object_add(wd->self, wd->view);
293              evas_object_hide(wd->view);
294           }
295
296         evas_object_image_file_set(wd->view, thumb_path, thumb_key);
297         r = evas_object_image_load_error_get(wd->view);
298         if (r != EVAS_LOAD_ERROR_NONE)
299           {
300              WRN("%s: %s", thumb_path, evas_load_error_str(r));
301              wd->thumb.thumb_path = eina_stringshare_ref(thumb_path);
302              wd->thumb.thumb_key = eina_stringshare_ref(thumb_key);
303              wd->thumb.format = ethumb_client_format_get(_elm_ethumb_client);
304              wd->thumb.retry = EINA_TRUE;
305
306              retry = eina_list_append(retry, wd);
307              return ;
308           }
309
310         evas_object_image_preload(wd->view, 0);
311         return ;
312      }
313
314    _thumb_ready(wd, thumb_path, thumb_key);
315
316    EINA_LIST_FOREACH_SAFE(retry, l, ll, wd)
317      if (_retry_thumb(wd))
318        retry = eina_list_remove_list(retry, l);
319
320    if (pending_request == 0)
321      EINA_LIST_FREE(retry, wd)
322        {
323           eina_stringshare_del(wd->thumb.thumb_path);
324           wd->thumb.thumb_path = NULL;
325
326           eina_stringshare_del(wd->thumb.thumb_key);
327           wd->thumb.thumb_key = NULL;
328
329           evas_object_del(wd->view);
330           wd->view = NULL;
331
332           edje_object_signal_emit(wd->frame, EDJE_SIGNAL_LOAD_ERROR, "elm");
333           evas_object_smart_callback_call(wd->self, SIG_LOAD_ERROR, NULL);
334        }
335
336    return;
337
338 err:
339    edje_object_signal_emit(wd->frame, EDJE_SIGNAL_LOAD_ERROR, "elm");
340    evas_object_smart_callback_call(wd->self, SIG_LOAD_ERROR, NULL);
341 }
342
343 static void
344 _elm_thumb_done(Ethumb_Client *client __UNUSED__, const char *thumb_path, const char *thumb_key, void *data)
345 {
346    Widget_Data *wd = data;
347
348    assert(wd->thumb.request);
349
350    pending_request--;
351    wd->thumb.request = NULL;
352
353    _finished_thumb(wd, thumb_path, thumb_key);
354 }
355
356 static void
357 _elm_thumb_error(Ethumb_Client *client __UNUSED__, void *data)
358 {
359    Widget_Data *wd = data;
360
361    assert(wd->thumb.request);
362
363    pending_request--;
364    wd->thumb.request = NULL;
365
366    ERR("could not generate thumbnail for %s (key: %s)", wd->thumb.file, wd->thumb.key ? wd->thumb.key : "");
367
368    edje_object_signal_emit(wd->frame, EDJE_SIGNAL_GENERATE_ERROR, "elm");
369    evas_object_smart_callback_call(wd->self, SIG_GENERATE_ERROR, NULL);
370 }
371
372 static void
373 _thumb_apply(Widget_Data *wd)
374 {
375    if (wd->thumb.request)
376      {
377         ethumb_client_thumb_async_cancel(_elm_ethumb_client, wd->thumb.request);
378         wd->thumb.request = NULL;
379      }
380    if (wd->thumb.retry)
381      {
382         retry = eina_list_remove(retry, wd);
383         wd->thumb.retry = EINA_FALSE;
384      }
385
386    if (!wd->file) return;
387
388    edje_object_signal_emit(wd->frame, EDJE_SIGNAL_PULSE_START, "elm");
389    edje_object_signal_emit(wd->frame, EDJE_SIGNAL_GENERATE_START, "elm");
390    evas_object_smart_callback_call(wd->self, SIG_GENERATE_START, NULL);
391
392    pending_request++;
393    ethumb_client_file_set(_elm_ethumb_client, wd->file, wd->key);
394    wd->thumb.request = ethumb_client_thumb_async_get(_elm_ethumb_client,
395                                                      _elm_thumb_done,
396                                                      _elm_thumb_error,
397                                                      wd);
398 }
399
400 static Eina_Bool
401 _thumb_apply_cb(void *data, int type __UNUSED__, void *ev __UNUSED__)
402 {
403    _thumb_apply(data);
404    return ECORE_CALLBACK_RENEW;
405 }
406
407 static void
408 _thumb_show(Widget_Data *wd)
409 {
410    evas_object_show(wd->frame);
411
412 <<<<<<< HEAD
413    if (elm_thumb_ethumb_client_connected())
414 =======
415    if (elm_thumb_ethumb_client_connected_get())
416 >>>>>>> remotes/origin/upstream
417      {
418         _thumb_apply(wd);
419         return;
420      }
421
422    if (!wd->eeh)
423      wd->eeh = ecore_event_handler_add(ELM_ECORE_EVENT_ETHUMB_CONNECT,
424                                        _thumb_apply_cb, wd);
425 }
426
427 static void
428 _thumb_show_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
429 {
430    _thumb_show(data);
431 }
432
433 static void
434 _thumb_hide_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
435 {
436    Widget_Data *wd = data;
437
438    evas_object_hide(wd->frame);
439
440    if (wd->thumb.request)
441      {
442         ethumb_client_thumb_async_cancel(_elm_ethumb_client, wd->thumb.request);
443         wd->thumb.request = NULL;
444
445         edje_object_signal_emit(wd->frame, EDJE_SIGNAL_GENERATE_STOP, "elm");
446         evas_object_smart_callback_call(wd->self, SIG_GENERATE_STOP, NULL);
447      }
448
449    if (wd->thumb.retry)
450      {
451         retry = eina_list_remove(retry, wd);
452         wd->thumb.retry = EINA_FALSE;
453      }
454
455    if (wd->eeh)
456      {
457         ecore_event_handler_del(wd->eeh);
458         wd->eeh = NULL;
459      }
460 }
461
462 #endif
463
464 #ifdef ELM_ETHUMB
465 static int _elm_need_ethumb = 0;
466
467 static void _on_die_cb(void *, Ethumb_Client *);
468
469 static void
470 _connect_cb(void *data __UNUSED__, Ethumb_Client *c, Eina_Bool success)
471 {
472    if (success)
473      {
474         ethumb_client_on_server_die_callback_set(c, _on_die_cb, NULL, NULL);
475         _elm_ethumb_connected = EINA_TRUE;
476         ecore_event_add(ELM_ECORE_EVENT_ETHUMB_CONNECT, NULL, NULL, NULL);
477      }
478    else
479      _elm_ethumb_client = NULL;
480 }
481
482 static void
483 _on_die_cb(void *data __UNUSED__, Ethumb_Client *c __UNUSED__)
484 {
485    ethumb_client_disconnect(_elm_ethumb_client);
486    _elm_ethumb_client = NULL;
487    _elm_ethumb_connected = EINA_FALSE;
488    _elm_ethumb_client = ethumb_client_connect(_connect_cb, NULL, NULL);
489 }
490 #endif
491
492 void
493 _elm_unneed_ethumb(void)
494 {
495 #ifdef ELM_ETHUMB
496    if (--_elm_need_ethumb) return;
497
498    ethumb_client_disconnect(_elm_ethumb_client);
499    _elm_ethumb_client = NULL;
500    ethumb_client_shutdown();
501    ELM_ECORE_EVENT_ETHUMB_CONNECT = 0;
502 #endif
503 }
504
505 static Eina_Bool
506 _elm_thumb_dropcb(void *data __UNUSED__, Evas_Object *o, Elm_Selection_Data *drop)
507 {
508    if ((!o) || (!drop) || (!drop->data)) return EINA_FALSE;
509    elm_thumb_file_set(o, drop->data, NULL);
510    return EINA_TRUE;
511 }
512
513 EAPI Eina_Bool
514 elm_need_ethumb(void)
515 {
516 #ifdef ELM_ETHUMB
517    if (_elm_need_ethumb++) return EINA_TRUE;
518    ELM_ECORE_EVENT_ETHUMB_CONNECT = ecore_event_type_new();
519    ethumb_client_init();
520    _elm_ethumb_client = ethumb_client_connect(_connect_cb, NULL, NULL);
521    return EINA_TRUE;
522 #else
523    return EINA_FALSE;
524 #endif
525 }
526
527 EAPI Evas_Object *
528 elm_thumb_add(Evas_Object *parent)
529 {
530    Evas *e;
531    Widget_Data *wd;
532    Evas_Object *obj;
533    Evas_Coord minw, minh;
534
535    ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
536
537    ELM_SET_WIDTYPE(widtype, "thumb");
538    elm_widget_type_set(obj, "thumb");
539    elm_widget_sub_object_add(parent, obj);
540    elm_widget_data_set(obj, wd);
541    elm_widget_del_hook_set(obj, _del_hook);
542    elm_widget_theme_hook_set(obj, _theme_hook);
543    elm_widget_can_focus_set(obj, EINA_FALSE);
544
545    wd->frame = edje_object_add(e);
546    _elm_theme_object_set(obj, wd->frame, "thumb", "base", "default");
547    elm_widget_resize_object_set(obj, wd->frame);
548
549    edje_object_size_min_calc(obj, &minw, &minh);
550    evas_object_size_hint_min_set(obj, minw, minh);
551
552    wd->self = obj;
553    wd->view = NULL;
554    wd->file = NULL;
555    wd->key = NULL;
556    wd->eeh = NULL;
557    wd->on_hold = EINA_FALSE;
558    wd->is_video = EINA_FALSE;
559    wd->was_video = EINA_FALSE;
560
561 #ifdef HAVE_ELEMENTARY_ETHUMB
562    wd->thumb.thumb_path = NULL;
563    wd->thumb.thumb_key = NULL;
564    wd->thumb.request = NULL;
565    evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_DOWN,
566                                   _mouse_down_cb, wd);
567    evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_UP,
568                                   _mouse_up_cb, wd);
569    evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW,
570                                   _thumb_show_cb, wd);
571    evas_object_event_callback_add(obj, EVAS_CALLBACK_HIDE,
572                                   _thumb_hide_cb, wd);
573 #endif
574
575    // TODO: convert Elementary to subclassing of Evas_Smart_Class
576    // TODO: and save some bytes, making descriptions per-class and not instance!
577    evas_object_smart_callbacks_descriptions_set(obj, _signals);
578    return obj;
579 }
580
581 EAPI void
582 elm_thumb_reload(Evas_Object *obj)
583 {
584    ELM_CHECK_WIDTYPE(obj, widtype);
585    Widget_Data *wd = elm_widget_data_get(obj);
586
587    eina_stringshare_replace(&(wd->thumb.file), NULL);
588    eina_stringshare_replace(&(wd->thumb.key), NULL);
589
590 #ifdef HAVE_ELEMENTARY_ETHUMB
591    if (evas_object_visible_get(obj))
592      _thumb_show(wd);
593 #endif
594 }
595
596 EAPI void
597 elm_thumb_file_set(Evas_Object *obj, const char *file, const char *key)
598 {
599    ELM_CHECK_WIDTYPE(obj, widtype);
600    Eina_Bool file_replaced, key_replaced;
601    Widget_Data *wd = elm_widget_data_get(obj);
602
603    file_replaced = eina_stringshare_replace(&(wd->file), file);
604    key_replaced = eina_stringshare_replace(&(wd->key), key);
605
606    if (file_replaced)
607      {
608         int prefix_size;
609         const char **ext, *ptr;
610         static const char *extensions[] =
611           {
612              ".avi", ".mp4", ".ogv", ".mov", ".mpg", ".wmv", NULL
613           };
614
615         prefix_size = eina_stringshare_strlen(wd->file) - 4;
616         if (prefix_size >= 0)
617           {
618              ptr = wd->file + prefix_size;
619              wd->is_video = EINA_FALSE;
620              for (ext = extensions; *ext; ext++)
621                if (!strcasecmp(ptr, *ext))
622                  {
623                     wd->is_video = EINA_TRUE;
624                     break;
625                  }
626           }
627      }
628
629    eina_stringshare_replace(&(wd->thumb.file), NULL);
630    eina_stringshare_replace(&(wd->thumb.key), NULL);
631
632 #ifdef HAVE_ELEMENTARY_ETHUMB
633    if (((file_replaced) || (key_replaced)) && (evas_object_visible_get(obj)))
634      _thumb_show(wd);
635 <<<<<<< HEAD
636 =======
637 #else
638    (void)key_replaced;
639 >>>>>>> remotes/origin/upstream
640 #endif
641 }
642
643 EAPI void
644 elm_thumb_file_get(const Evas_Object *obj, const char **file, const char **key)
645 {
646    ELM_CHECK_WIDTYPE(obj, widtype);
647    Widget_Data *wd = elm_widget_data_get(obj);
648
649    if (file)
650      *file = wd->file;
651    if (key)
652      *key = wd->key;
653 }
654
655 EAPI void
656 elm_thumb_path_get(const Evas_Object *obj, const char **file, const char **key)
657 {
658    ELM_CHECK_WIDTYPE(obj, widtype);
659    Widget_Data *wd = elm_widget_data_get(obj);
660
661    if (file)
662      *file = wd->thumb.file;
663    if (key)
664      *key = wd->thumb.key;
665 }
666
667 EAPI void
668 elm_thumb_animate_set(Evas_Object *obj, Elm_Thumb_Animation_Setting setting)
669 {
670    ELM_CHECK_WIDTYPE(obj, widtype);
671    Widget_Data *wd = elm_widget_data_get(obj);
672
673    EINA_SAFETY_ON_TRUE_RETURN(setting >= ELM_THUMB_ANIMATION_LAST);
674
675    wd->anim_setting = setting;
676    if (setting == ELM_THUMB_ANIMATION_LOOP)
677      edje_object_signal_emit(wd->view, "animate_loop", "");
678    else if (setting == ELM_THUMB_ANIMATION_START)
679      edje_object_signal_emit(wd->view, "animate", "");
680    else if (setting == ELM_THUMB_ANIMATION_STOP)
681      edje_object_signal_emit(wd->view, "animate_stop", "");
682 }
683
684 EAPI Elm_Thumb_Animation_Setting
685 elm_thumb_animate_get(const Evas_Object *obj)
686 {
687    ELM_CHECK_WIDTYPE(obj, widtype) ELM_THUMB_ANIMATION_LAST;
688    Widget_Data *wd = elm_widget_data_get(obj);
689
690    return wd->anim_setting;
691 }
692
693 EAPI void *
694 elm_thumb_ethumb_client_get(void)
695 {
696    return _elm_ethumb_client;
697 }
698
699 EAPI Eina_Bool
700 <<<<<<< HEAD
701 elm_thumb_ethumb_client_connected(void)
702 =======
703 elm_thumb_ethumb_client_connected_get(void)
704 >>>>>>> remotes/origin/upstream
705 {
706    return _elm_ethumb_connected;
707 }
708
709 EAPI Eina_Bool
710 elm_thumb_editable_set(Evas_Object *obj, Eina_Bool edit)
711 {
712    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
713    Widget_Data *wd = elm_widget_data_get(obj);
714
715    if (!wd) return EINA_FALSE;
716    edit = !!edit;
717    if (wd->edit == edit) return EINA_TRUE;
718
719    wd->edit = edit;
720    if (wd->edit)
721      elm_drop_target_add(obj, ELM_SEL_FORMAT_IMAGE,
722                          _elm_thumb_dropcb, obj);
723    else
724      elm_drop_target_del(obj);
725
726    return EINA_TRUE;
727 }
728
729 EAPI Eina_Bool
730 elm_thumb_editable_get(const Evas_Object *obj)
731 {
732    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
733    Widget_Data *wd = elm_widget_data_get(obj);
734
735    if (!wd) return EINA_FALSE;
736    return wd->edit;
737 }
738
739 /* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-3f0^-2{2(0W1st0 :*/