viewer: add movie/video/photo viewer 86/42286/4
authorMinkyu Kang <mk7.kang@samsung.com>
Thu, 25 Jun 2015 08:58:31 +0000 (17:58 +0900)
committerMinkyu Kang <mk7.kang@samsung.com>
Fri, 26 Jun 2015 04:59:35 +0000 (21:59 -0700)
Initiall support for UI of viewers.
This patch is including test codes for making media list.

Change-Id: I896f5a3463643f38bdb5644f806b070442b1b402
Signed-off-by: Minkyu Kang <mk7.kang@samsung.com>
CMakeLists.txt
include/view/viewer.h
res/edc/view/viewer.edc
res/images/ic_title_favorite.png [moved from res/edc/images/ic_title_favorite.png with 100% similarity]
src/view/viewer.c

index 15adc8e..5f67dbe 100644 (file)
@@ -83,4 +83,5 @@ CONFIGURE_FILE(${PACKAGE_NAME}.xml.in ${PACKAGE_NAME}.xml)
 
 INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${BINDIR})
 INSTALL(FILES ${PACKAGE_NAME}.xml DESTINATION ${PACKAGEDIR})
+INSTALL(DIRECTORY ${CMAKE_SOURCE_DIR}/res/images DESTINATION ${RESDIR})
 ADD_SUBDIRECTORY(res/edc)
index f50bc40..c9e5f32 100644 (file)
@@ -30,6 +30,7 @@
 #define PART_VIEWER_PAGE "part.viewer_page"
 #define PART_VIEWER_PROGRESS "part.viewer_progress"
 #define PART_VIEWER_TOTAL "part.viewer_total"
+#define PART_VIEWER_FAVORITE "part.viewer_favorite"
 
 /* signal */
 #define SIG_SET_PLAY "set,play,icon"
@@ -38,7 +39,7 @@
 #define SIG_BTN_CALLBACK "btn,callback"
 
 /* images */
-#define IMAGE_VIEWER_FAVORITE "ic_title_favorite.png"
+#define IMAGE_VIEWER_FAVORITE IMAGEDIR"/ic_title_favorite.png"
 
 #define IMAGE_VIEWER_PREV_FOCUS "btn_view_contr_previous_foc.png"
 #define IMAGE_VIEWER_PREV_NORMAL "btn_view_contr_previous_nor.png"
index 84cb95a..e3c6573 100644 (file)
@@ -16,9 +16,6 @@
 
 group {
        name: GRP_VIEWER_VIEW;
-       images {
-               image: IMAGE_VIEWER_FAVORITE COMP;
-       }
        parts {
                part {
                        name: "bg";
@@ -187,7 +184,8 @@ group {
                        }
                }
                part {
-                       name: "favorite_icon";
+                       name: PART_VIEWER_FAVORITE;
+                       type: SWALLOW;
                        scale: 1;
                        description {
                                state: "default" 0.0;
@@ -200,10 +198,6 @@ group {
                                        to: "padding_right";
                                        relative: 0.0 0.5;
                                }
-                               /* It will be modified to SWALLOW area */
-                               image {
-                                       normal: IMAGE_VIEWER_FAVORITE;
-                               }
                                fixed: 1 1;
                                align: 1.0 0.5;
                        }
index 656ae4d..4202bac 100644 (file)
 #include <app_debug.h>
 #include <viewmgr.h>
 #include <layoutmgr.h>
+#include <media_content.h>
+#include <media_info.h>
+#include <app_media.h>
 
 #include "define.h"
+#include "util/controller.h"
+
+#define STYLE_VIEWER_BTN "viewer_btn"
+#define PART_VIEWER_BTN "control_btn"
+
+#define VIDEO_COPYRIGHT "Unknown"
+
+enum {
+       VIEWER_MOVIE,
+       VIEWER_PHOTO,
+       VIEWER_VIDEO,
+       VIEWER_MAX
+};
+
+struct _viewer {
+       struct controller *ctl[VIEWER_MAX];
+       int cur;
+};
+
+struct _playlist {
+       Eina_List *list;
+       int cur;
+};
 
 struct _priv {
        Evas_Object *win;
        Evas_Object *base;
+
+       struct _viewer viewer;
+       struct _playlist playlist;
+};
+
+struct _btn_info {
+       const char *name;
+       int loc;
+};
+
+static struct _btn_info btn_movie[] = {
+       {
+               .name = "prev",
+               .loc = 0,
+       },
+       {
+               .name = "rew",
+               .loc = 1,
+       },
+       {
+               .name = "play",
+               .loc = 2,
+       },
+       {
+               .name = "ff",
+               .loc = 3,
+       },
+       {
+               .name = "next",
+               .loc = 4,
+       },
+};
+
+static struct _btn_info btn_photo[] = {
+       {
+               .name = "prev_photo",
+               .loc = 0,
+       },
+       {
+               .name = "next_photo",
+               .loc = 4,
+       },
+};
+
+static struct _btn_info btn_video[] = {
+       {
+               .name = "prev",
+               .loc = 0,
+       },
+       {
+               .name = "rew",
+               .loc = 1,
+       },
+       {
+               .name = "play",
+               .loc = 2,
+       },
+       {
+               .name = "ff",
+               .loc = 3,
+       },
+       {
+               .name = "next",
+               .loc = 4,
+       },
+};
+
+struct _viewer_info {
+       struct _btn_info *btns;
+       int btn_count;
+       int focus_loc;
+};
+
+static struct _viewer_info viewer_info[] = {
+       {
+               .btns = btn_movie,
+               .btn_count = 5,
+               .focus_loc = 2,
+       },
+       {
+               .btns = btn_photo,
+               .btn_count = 2,
+               .focus_loc = 1,
+       },
+       {
+               .btns = btn_video,
+               .btn_count = 5,
+               .focus_loc = 4,
+       },
 };
 
+/* FIXME: test function */
+static bool _media(media_info_h media_h, void *dt)
+{
+       struct _priv *priv;
+       app_media *am;
+
+       priv = dt;
+
+       am = app_media_create(media_h);
+
+       priv->playlist.list = eina_list_append(priv->playlist.list, am);
+
+       return true;
+}
+
+static void _media_test(struct _priv *priv, int mode)
+{
+       char *path = "/home/owner/content/Videos/Xmen-Days_of_Future_Past.mp4";
+       filter_h filter;
+       char buf[1024];
+       int r;
+
+       r = media_filter_create(&filter);
+       if (r != MEDIA_CONTENT_ERROR_NONE) {
+               _ERR("Media Filter Creation Failed");
+               return;
+       }
+
+       if (mode)
+               snprintf(buf, sizeof(buf), "MEDIA_PATH = \"%s\"", path);
+       else
+               snprintf(buf, sizeof(buf), "MEDIA_TYPE=0 OR MEDIA_TYPE=1");
+
+       r = media_filter_set_condition(filter, buf,
+                       MEDIA_CONTENT_COLLATE_DEFAULT);
+       if (r != MEDIA_CONTENT_ERROR_NONE) {
+               _ERR("Fail to set filter condition");
+               media_filter_destroy(filter);
+               return;
+       }
+
+       media_content_connect();
+
+       r = media_info_foreach_media_from_db(filter, _media, priv);
+       if (r != MEDIA_CONTENT_ERROR_NONE) {
+               _ERR("MEDIA CONTENT ERROR: %d", r);
+               media_filter_destroy(filter);
+               media_content_disconnect();
+               return;
+       }
+
+       media_filter_destroy(filter);
+       media_content_disconnect();
+}
+/* FIXME: test function end */
+
+/*
+ * NOTE: Workaround
+ * we assumed that if video content have the copyright then it's a movie.
+ */
+static inline bool _check_movie_type(app_media_info *mi)
+{
+       return strcmp(mi->video->copyright, VIDEO_COPYRIGHT);
+}
+
+static void _get_timestr(char *str, int size, unsigned int ms)
+{
+       int sec;
+
+       sec = ms / 1000;
+
+       snprintf(str, size, "%02d:%02d:%02d",
+                       sec / 3600, (sec % 3600) / 60, sec % 60);
+}
+
+static void _draw_title_bar(struct _priv *priv, int id, app_media_info *mi)
+{
+       char buf[32] = {0,};
+       struct tm tm;
+
+       if (id == VIEWER_MOVIE) {
+               elm_object_part_text_set(priv->base,
+                               PART_VIEWER_TITLE, mi->title);
+       } else {
+               localtime_r(&mi->modified_time, &tm);
+               strftime(buf, sizeof(buf), "%a, %d %b", &tm);
+
+               elm_object_part_text_set(priv->base, PART_VIEWER_DATE, buf);
+
+               snprintf(buf, sizeof(buf), "%d / %d", priv->playlist.cur + 1,
+                               eina_list_count(priv->playlist.list));
+               elm_object_part_text_set(priv->base, PART_VIEWER_PAGE, buf);
+       }
+}
+
+static void _draw_time_info(struct _priv *priv, int id, app_media_info *mi)
+{
+       char progress[32] = {0,};
+       char duration[32] = {0,};
+       char total[32] = {0,};
+
+       if (id != VIEWER_PHOTO) {
+               _get_timestr(progress, sizeof(progress), mi->video->position);
+               _get_timestr(duration, sizeof(duration), mi->video->duration);
+               snprintf(total, sizeof(total), "/ %s", duration);
+       }
+
+       elm_object_part_text_set(priv->base, PART_VIEWER_PROGRESS, progress);
+       elm_object_part_text_set(priv->base, PART_VIEWER_TOTAL, total);
+}
+
+static void _draw_favorite_icon(struct _priv *priv, int id, app_media_info *mi)
+{
+       Evas_Object *img;
+
+       if (!mi->favorite)
+               return;
+
+       img = elm_image_add(priv->base);
+       if (!img)
+               return;
+
+       elm_image_file_set(img, IMAGE_VIEWER_FAVORITE, NULL);
+
+       evas_object_show(img);
+       elm_object_part_content_set(priv->base, PART_VIEWER_FAVORITE, img);
+}
+
+static bool _viewer_show(struct _priv *priv, int cur)
+{
+       struct _viewer_info *info;
+       struct controller *ctl;
+       int id;
+       app_media *am;
+       app_media_info *mi;
+
+       am = eina_list_nth(priv->playlist.list, cur);
+       if (!am) {
+               _ERR("failed to get app_media");
+               return false;
+       }
+
+       priv->playlist.cur = cur;
+
+       mi = app_media_get_info(am);
+       if (!mi) {
+               _ERR("failed to getting media info");
+               return false;
+       }
+
+       switch (mi->media_type) {
+       case MEDIA_CONTENT_TYPE_IMAGE:
+               id = VIEWER_PHOTO;
+               break;
+       case MEDIA_CONTENT_TYPE_VIDEO:
+               if (_check_movie_type(mi))
+                       id = VIEWER_MOVIE;
+               else
+                       id = VIEWER_VIDEO;
+               break;
+       default:
+               return false;
+       }
+
+       info = &viewer_info[id];
+       ctl = priv->viewer.ctl[id];
+       priv->viewer.cur = id;
+
+       ctl->ops->show(ctl->handle);
+       ctl->ops->focus(ctl->handle, info->focus_loc, true);
+
+       _draw_title_bar(priv, id, mi);
+       _draw_time_info(priv, id, mi);
+       _draw_favorite_icon(priv, id, mi);
+
+       return true;
+}
+
+static void _viewer_hide(struct _priv *priv)
+{
+       struct controller *ctl;
+
+       ctl = priv->viewer.ctl[priv->viewer.cur];
+       ctl->ops->hide(ctl->handle);
+
+       elm_object_part_content_unset(priv->base, PART_VIEWER_FAVORITE);
+}
+
+static bool _viewer_add(struct _priv *priv, int id)
+{
+       struct _viewer_info *info;
+       struct controller *ctl;
+       int i;
+
+       info = &viewer_info[id];
+
+       ctl = controller_create(priv->base);
+       if (!ctl) {
+               _ERR("failed to create controller");
+               return false;
+       }
+
+       for (i = 0; i < info->btn_count; i++) {
+               ctl->ops->add_control(ctl->handle,
+                               info->btns[i].name, info->btns[i].loc,
+                               STYLE_VIEWER_BTN, PART_VIEWER_BTN);
+       }
+
+       priv->viewer.ctl[id] = ctl;
+
+       return true;
+}
+
+static void _viewer_delete(struct _priv *priv)
+{
+       struct controller *ctl;
+       int i;
+
+       for (i = 0; i < VIEWER_MAX; i++) {
+               ctl = priv->viewer.ctl[i];
+               if (ctl)
+                       controller_destroy(ctl->handle);
+       }
+}
+
+static bool _ui_init(struct _priv *priv)
+{
+       bool r;
+       int i;
+
+       for (i = 0; i < VIEWER_MAX; i++) {
+               r = _viewer_add(priv, i);
+               if (!r)
+                       goto err;
+       }
+
+       return true;
+
+err:
+       _viewer_delete(priv);
+       return false;
+}
+
 static Evas_Object *_create(Evas_Object *win, void *data)
 {
        struct _priv *priv;
        Evas_Object *base;
+       bool r;
 
        if (!win) {
                _ERR("failed to get win object");
@@ -58,6 +417,18 @@ static Evas_Object *_create(Evas_Object *win, void *data)
        priv->win = win;
        priv->base = base;
 
+       priv->playlist.list = NULL;
+       priv->playlist.cur = 0;
+
+       r = _ui_init(priv);
+       if (!r) {
+               _ERR("failed to init UI");
+               return NULL;
+       }
+
+       /* FIXME: test code */
+       _media_test(priv, 0);
+
        viewmgr_set_view_data(VIEW_VIEWER, priv);
 
        return base;
@@ -74,6 +445,9 @@ static void _show(void *view_data)
 
        priv = view_data;
 
+       /* FIXME: test code */
+       _viewer_show(priv, 1);
+
        evas_object_show(priv->base);
 }
 
@@ -88,12 +462,15 @@ static void _hide(void *view_data)
 
        priv = view_data;
 
+       _viewer_hide(priv);
+
        evas_object_hide(priv->base);
 }
 
 static void _destroy(void *view_data)
 {
        struct _priv *priv;
+       app_media *am;
 
        if (!view_data) {
                _ERR("failed to get view data");
@@ -102,6 +479,11 @@ static void _destroy(void *view_data)
 
        priv = view_data;
 
+       _viewer_delete(priv);
+
+       EINA_LIST_FREE(priv->playlist.list, am)
+               app_media_destroy(am);
+
        evas_object_del(priv->base);
 
        free(priv);