elementary: Privide a new api to elm_photo : elm_photo_thumb_set.
authorcaptainigloo <captainigloo@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Thu, 1 Sep 2011 19:14:32 +0000 (19:14 +0000)
committercaptainigloo <captainigloo@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Thu, 1 Sep 2011 19:14:32 +0000 (19:14 +0000)
It works like elm_icon_thumb_set : it generates the thumb of the file passed as argument.

git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/elementary@63063 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

src/bin/test_photo.c
src/lib/Elementary.h.in
src/lib/elm_photo.c

index fd7b77b..1e3cf1d 100644 (file)
@@ -27,6 +27,8 @@ test_photo(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info
         "wood_01.jpg"
      };
 
+   elm_need_ethumb();
+
    win = elm_win_add(NULL, "photo", ELM_WIN_BASIC);
    elm_win_title_set(win, "Photo");
    elm_win_autodel_set(win, EINA_TRUE);
@@ -50,7 +52,10 @@ test_photo(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info
              n++;
              if (n >= 9) n = 0;
              elm_photo_size_set(ph, 80);
-             elm_photo_file_set(ph, buf);
+             if (n == 8)
+               elm_photo_thumb_set(ph, buf, NULL);
+             else
+               elm_photo_file_set(ph, buf);
              elm_photo_editable_set(ph, 1);
              evas_object_size_hint_weight_set(ph, EVAS_HINT_EXPAND,
                                               EVAS_HINT_EXPAND);
index b9cbc31..131e6da 100644 (file)
@@ -12033,6 +12033,17 @@ extern "C" {
     */
    EAPI Eina_Bool    elm_photo_file_set(Evas_Object *obj, const char *file) EINA_ARG_NONNULL(1);
 
+    /**
+    * Set the file that will be used as thumbnail in the photo.
+    *
+    * @param obj The photo object.
+    * @param file The path to file that will be used as thumb.
+    * @param group The key used in case of an EET file.
+    *
+    * @ingroup Photo
+    */
+   EAPI void         elm_photo_thumb_set(const Evas_Object *obj, const char *file, const char *group) EINA_ARG_NONNULL(1, 2);
+
    /**
     * Set the size that will be used on the photo
     *
index 4371e4e..8eee9c1 100644 (file)
@@ -10,8 +10,36 @@ struct _Widget_Data
    int size;
    Eina_Bool fill;
    Ecore_Timer *longtimer;
+
+#ifdef HAVE_ELEMENTARY_ETHUMB
+   struct {
+      int id;
+
+      struct {
+         const char *path;
+         const char *key;
+      } file, thumb;
+
+      Ethumb_Exists *exists;
+
+      Ecore_Event_Handler *eeh;
+
+      Ethumb_Thumb_Format format;
+
+      Eina_Bool retry : 1;
+   } thumb;
+#endif
+
 };
 
+#ifdef HAVE_ELEMENTARY_ETHUMB
+static Eina_List *_elm_icon_retry = NULL;
+static int _icon_pending_request = 0;
+
+static void _icon_thumb_exists(Ethumb_Client *client __UNUSED__, Ethumb_Exists *thread, Eina_Bool exists, void *data);
+static void _icon_thumb_stop(Widget_Data *wd, void *ethumbd);
+#endif
+
 static const char *widtype = NULL;
 static void _del_hook(Evas_Object *obj);
 static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl);
@@ -36,7 +64,24 @@ static void
 _del_hook(Evas_Object *obj)
 {
    Widget_Data *wd = elm_widget_data_get(obj);
+#ifdef HAVE_ELEMENTARY_ETHUMB
+   Ethumb_Client *ethumbd;
+#endif
    if (!wd) return;
+
+#ifdef HAVE_ELEMENTARY_ETHUMB
+   ethumbd = elm_thumb_ethumb_client_get();
+   _icon_thumb_stop(wd, ethumbd);
+
+   eina_stringshare_del(wd->thumb.file.path);
+   eina_stringshare_del(wd->thumb.file.key);
+   eina_stringshare_del(wd->thumb.thumb.path);
+   eina_stringshare_del(wd->thumb.thumb.key);
+
+   if (wd->thumb.eeh)
+     ecore_event_handler_del(wd->thumb.eeh);
+#endif
+
    free(wd);
 }
 
@@ -107,6 +152,11 @@ _icon_move_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, v
 
         edje_object_message_send(wd->frm, EDJE_MESSAGE_INT_SET, 0, msg);
      }
+
+#ifdef HAVE_ELEMENTARY_ETHUMB
+   if (wd->thumb.file.path)
+     elm_photo_thumb_set(data, wd->thumb.file.path, wd->thumb.file.key);
+#endif
 }
 
 
@@ -198,6 +248,227 @@ _mouse_up(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *eve
    evas_object_smart_callback_call(data, SIG_CLICKED, NULL);
 }
 
+static inline int
+_icon_size_min_get(Evas_Object *icon)
+{
+   int size;
+   _els_smart_icon_size_get(icon, &size, NULL);
+   return (size < 32) ? 32 : size;
+}
+
+
+#ifdef HAVE_ELEMENTARY_ETHUMB
+static void
+_icon_thumb_stop(Widget_Data *wd, void *ethumbd)
+{
+   if (wd->thumb.id >= 0)
+     {
+        ethumb_client_generate_cancel(ethumbd, wd->thumb.id, NULL, NULL, NULL);
+        wd->thumb.id = -1;
+        _icon_pending_request--;
+     }
+
+   if (wd->thumb.exists)
+     {
+        ethumb_client_thumb_exists_cancel(wd->thumb.exists, _icon_thumb_exists, wd);
+        wd->thumb.exists = NULL;
+        _icon_pending_request--;
+     }
+
+   if (wd->thumb.retry)
+     {
+        _elm_icon_retry = eina_list_remove(_elm_icon_retry, wd);
+        wd->thumb.retry = EINA_FALSE;
+     }
+}
+
+static Eina_Bool
+_icon_thumb_display(Widget_Data *wd)
+{
+   Eina_Bool ret = EINA_FALSE;
+
+   if (wd->thumb.format == ETHUMB_THUMB_EET)
+     {
+        static const char *extensions[] = {
+          ".avi", ".mp4", ".ogv", ".mov", ".mpg", ".wmv", NULL
+        };
+        const char **ext, *ptr;
+        int prefix_size;
+        Eina_Bool video = EINA_FALSE;
+
+        prefix_size = eina_stringshare_strlen(wd->thumb.file.path) - 4;
+        if (prefix_size >= 0)
+          {
+             ptr = wd->thumb.file.path + prefix_size;
+             for (ext = extensions; *ext; ++ext)
+               if (!strcasecmp(ptr, *ext))
+                 {
+                    video = EINA_TRUE;
+                    break;
+                 }
+          }
+
+        if (video)
+          ret = _els_smart_icon_file_edje_set(wd->img, wd->thumb.thumb.path, wd->thumb.thumb.key);
+     }
+
+   if (!ret)
+     ret = _els_smart_icon_file_key_set(wd->img, wd->thumb.thumb.path, wd->thumb.thumb.key);
+
+   return ret;
+}
+
+static Eina_Bool
+_icon_thumb_retry(Widget_Data *wd)
+{
+   return _icon_thumb_display(wd);
+}
+
+static void
+_icon_thumb_cleanup(Ethumb_Client *ethumbd)
+{
+   Eina_List *l, *ll;
+   Widget_Data *wd;
+
+   EINA_LIST_FOREACH_SAFE(_elm_icon_retry, l, ll, wd)
+     if (_icon_thumb_retry(wd))
+       {
+          _elm_icon_retry = eina_list_remove_list(_elm_icon_retry, l);
+          wd->thumb.retry = EINA_FALSE;
+       }
+
+   if (_icon_pending_request == 0)
+     EINA_LIST_FREE(_elm_icon_retry, wd)
+       _icon_thumb_stop(wd, ethumbd);
+}
+
+static void
+_icon_thumb_finish(Widget_Data *wd, Ethumb_Client *ethumbd)
+{
+   const char *file = NULL, *group = NULL;
+   Eina_Bool ret;
+
+   _els_smart_icon_file_get(wd->img, &file, &group);
+   file = eina_stringshare_ref(file);
+   group = eina_stringshare_ref(group);
+
+   ret = _icon_thumb_display(wd);
+
+   if (!ret && file)
+     {
+        const char *p;
+
+        if (!wd->thumb.retry)
+          {
+             _elm_icon_retry = eina_list_append(_elm_icon_retry, wd);
+             wd->thumb.retry = EINA_TRUE;
+          }
+
+        /* Back to previous image */
+        if (((p = strrchr(file, '.'))) && (!strcasecmp(p, ".edj")))
+          _els_smart_icon_file_edje_set(wd->img, file, group);
+        else
+          _els_smart_icon_file_key_set(wd->img, file, group);
+     }
+
+   _icon_thumb_cleanup(ethumbd);
+
+   eina_stringshare_del(file);
+   eina_stringshare_del(group);
+}
+
+static void
+_icon_thumb_cb(void *data,
+               Ethumb_Client *ethumbd,
+               int id,
+               const char *file __UNUSED__,
+               const char *key __UNUSED__,
+               const char *thumb_path,
+               const char *thumb_key,
+               Eina_Bool success)
+{
+   Widget_Data *wd = data;
+
+   EINA_SAFETY_ON_FALSE_RETURN(wd->thumb.id == id);
+   wd->thumb.id = -1;
+
+   _icon_pending_request--;
+
+   if (success)
+     {
+        eina_stringshare_replace(&wd->thumb.thumb.path, thumb_path);
+        eina_stringshare_replace(&wd->thumb.thumb.key, thumb_key);
+        wd->thumb.format = ethumb_client_format_get(ethumbd);
+
+        _icon_thumb_finish(wd, ethumbd);
+     }
+   else
+     {
+        ERR("could not generate thumbnail for %s (key: %s)", file, key);
+        _icon_thumb_cleanup(ethumbd);
+     }
+}
+
+static void
+_icon_thumb_exists(Ethumb_Client *client __UNUSED__, Ethumb_Exists *thread, Eina_Bool exists, void *data)
+{
+   Widget_Data *wd = data;
+   Ethumb_Client *ethumbd;
+
+   if (ethumb_client_thumb_exists_check(thread))
+     return ;
+
+   wd->thumb.exists = NULL;
+
+   ethumbd = elm_thumb_ethumb_client_get();
+
+   if (exists)
+     {
+        const char *thumb_path, *thumb_key;
+
+        _icon_pending_request--;
+        ethumb_client_thumb_path_get(ethumbd, &thumb_path, &thumb_key);
+        eina_stringshare_replace(&wd->thumb.thumb.path, thumb_path);
+        eina_stringshare_replace(&wd->thumb.thumb.key, thumb_key);
+        wd->thumb.format = ethumb_client_format_get(ethumbd);
+
+        _icon_thumb_finish(wd, ethumbd);
+     }
+   else if ((wd->thumb.id = ethumb_client_generate(ethumbd, _icon_thumb_cb, wd, NULL)) == -1)
+     {
+        ERR("Generate was unable to start !");
+        /* Failed to generate thumbnail */
+        _icon_pending_request--;
+     }
+}
+
+static void
+_icon_thumb_apply(Widget_Data *wd)
+{
+   Ethumb_Client *ethumbd;
+
+   ethumbd = elm_thumb_ethumb_client_get();
+
+   _icon_thumb_stop(wd, ethumbd);
+
+   if (!wd->thumb.file.path) return ;
+
+   _icon_pending_request++;
+   if (!ethumb_client_file_set(ethumbd, wd->thumb.file.path, wd->thumb.file.key)) return ;
+   ethumb_client_size_set(ethumbd, _icon_size_min_get(wd->img), _icon_size_min_get(wd->img));
+   wd->thumb.exists = ethumb_client_thumb_exists(ethumbd, _icon_thumb_exists, wd);
+}
+
+static Eina_Bool
+_icon_thumb_apply_cb(void *data, int type __UNUSED__, void *ev __UNUSED__)
+{
+   Widget_Data *wd = data;
+
+   _icon_thumb_apply(wd);
+   return ECORE_CALLBACK_RENEW;
+}
+#endif
+
 EAPI Evas_Object *
 elm_photo_add(Evas_Object *parent)
 {
@@ -248,6 +519,10 @@ elm_photo_add(Evas_Object *parent)
 
    evas_object_smart_callbacks_descriptions_set(obj, _signals);
 
+#ifdef HAVE_ELEMENTARY_ETHUMB
+   wd->thumb.id = -1;
+#endif
+
    _mirrored_set(obj, elm_widget_mirrored_get(obj));
    _sizing_eval(obj);
    return obj;
@@ -303,4 +578,32 @@ elm_photo_editable_set(Evas_Object *obj, Eina_Bool set)
    _els_smart_icon_edit_set(wd->img, set, obj);
 }
 
+EAPI void
+elm_photo_thumb_set(const Evas_Object *obj, const char *file, const char *group)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+
+#ifdef HAVE_ELEMENTARY_ETHUMB
+   eina_stringshare_replace(&wd->thumb.file.path, file);
+   eina_stringshare_replace(&wd->thumb.file.key, group);
+
+   if (elm_thumb_ethumb_client_connected())
+     {
+        _icon_thumb_apply(wd);
+        return ;
+     }
+
+   if (!wd->thumb.eeh)
+     {
+        wd->thumb.eeh = ecore_event_handler_add(ELM_ECORE_EVENT_ETHUMB_CONNECT, _icon_thumb_apply_cb, wd);
+     }
+#else
+   (void) obj;
+   (void) file;
+   (void) group;
+#endif
+}
+
 /* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-3f0^-2{2(0W1st0 :*/