From: jinwoo.shin Date: Fri, 10 Jul 2015 10:58:27 +0000 (+0900) Subject: Add channel next/prev event X-Git-Tag: accepted/tizen/tv/20150728.070558~10 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=183923c7714edec234ad2f944492ffb48d83bdfc;p=profile%2Ftv%2Fapps%2Fnative%2Fair_livetv.git Add channel next/prev event Change-Id: Ie8a3182aa1db8d16bb0d648b418324bda1d56994 Signed-off-by: jinwoo.shin --- diff --git a/data/view/channelinfo.edc b/data/view/channelinfo.edc index b97ee55..3beca20 100644 --- a/data/view/channelinfo.edc +++ b/data/view/channelinfo.edc @@ -550,5 +550,23 @@ group { fixed, 1 1; } } + part { + name, PART_CHANNELINFO_STATUS; + type, SWALLOW; + scale, 1; + description { + state, "default" 0.0; + visible, 0; + } + } + part { + name, PART_CHANNELINFO_TIME; + type, TEXT; + scale, 1; + description { + state, "default" 0.0; + visible, 0; + } + } } } diff --git a/include/tv.h b/include/tv.h index f98574a..40a1458 100644 --- a/include/tv.h +++ b/include/tv.h @@ -84,10 +84,13 @@ int tv_channel_del_channel(int service_id); int tv_channel_lock_channel(int service_id, char *password); int tv_channel_unlock_channel(int service_id, char *password); const struct tv_channel_info *tv_channel_get_info(void); +const struct tv_channel_info *tv_channel_clone_info( + const struct tv_channel_info *channel_info); void tv_channel_del_info(const struct tv_channel_info *channel_info); int tv_epg_get_program(int service_id, struct tv_program_request *request); -int tv_epg_get_cache_program(int service_id, struct tv_program_request *request); +int tv_epg_get_cache_program(int service_id, + struct tv_program_request *request); int tv_epg_get_program_list(int service_id, struct tv_program_request *request); void tv_signal_cb_set(void (*cb)(void *data, int is_signal), void *data); diff --git a/include/view_channelinfo.h b/include/view_channelinfo.h index 6ced573..6637f1a 100644 --- a/include/view_channelinfo.h +++ b/include/view_channelinfo.h @@ -19,7 +19,8 @@ enum _update_type { UPDATE_TYPE_TIMER, - UPDATE_TYPE_INPUT, + UPDATE_TYPE_INPUT_KEY_DOWN, + UPDATE_TYPE_INPUT_KEY_UP, }; void draw_channel_info(Evas_Object *obj, const struct tv_channel_info *channel_info); diff --git a/src/layout_channelinfo_list.c b/src/layout_channelinfo_list.c index 03249a5..5d9ce51 100644 --- a/src/layout_channelinfo_list.c +++ b/src/layout_channelinfo_list.c @@ -25,6 +25,11 @@ #include "tv.h" #include "view_channelinfo.h" +enum _order { + CHANNEL_NEXT, + CHANNEL_PREV +}; + struct _priv { Evas_Object *base; Evas_Object *layout; @@ -32,23 +37,107 @@ struct _priv { Evas_Object *current_channel; Evas_Object *next_channel; + const struct tv_channel_info *channel_info; layoutmgr *lmgr; }; +static int _set_next_channel(struct _priv *priv, int order) +{ + const struct tv_channel_info *next, *current, *channel; + Eina_List *channel_list, *l; + + if (priv->channel_info) + current = priv->channel_info; + else { + current = tv_channel_get_info(); + if (!current) { + _ERR("failed to get channel info"); + + return -1; + } + } + + channel_list = tv_channel_get_list(); + if (!channel_list) { + _ERR("failed to get channel list"); + return -1; + } + + if (order == CHANNEL_PREV) + channel_list = eina_list_reverse(channel_list); + + next = NULL; + EINA_LIST_FOREACH(channel_list, l, channel) { + if (channel->service_id == current->service_id) { + next = eina_list_data_get(eina_list_next(l)); + break; + } + } + + if (!next) + next = eina_list_data_get(channel_list); + + priv->channel_info = tv_channel_clone_info(next); + + tv_channel_del_info(current); + tv_channel_del_list(channel_list); + + return 0; +} + static void _update_channel_info(struct _priv *priv) { - const struct tv_channel_info *current_channel; + const struct tv_channel_info *prev, *current, *next, *channel; + Eina_List *channel_list, *l; + + if (priv->channel_info) + current = priv->channel_info; + else { + current = tv_channel_get_info(); + if (!current) { + _ERR("failed to get channel info"); + + return; + } + } - current_channel = tv_channel_get_info(); - if (!current_channel) { - _ERR("failed to get channel info"); + draw_channel_info(priv->current_channel, current); + channel_list = tv_channel_get_list(); + if (!channel_list) { + _ERR("failed to get channel list"); return; } - draw_channel_info(priv->current_channel, current_channel); + prev = NULL; + next = NULL; + EINA_LIST_FOREACH(channel_list, l, channel) { + if (channel->service_id == current->service_id) { + prev = eina_list_data_get(eina_list_prev(l)); + next = eina_list_data_get(eina_list_next(l)); + break; + } + } + + if (!prev) { + prev = eina_list_data_get(eina_list_last(channel_list)); + if (prev == current) + prev = NULL; + } + + if (!next) { + next = eina_list_data_get(channel_list); + if (next == current) + next = NULL; + } - tv_channel_del_info(current_channel); + if (prev) + draw_channel_info(priv->prev_channel, prev); + + if (next) + draw_channel_info(priv->next_channel, next); + + tv_channel_del_list(channel_list); } static bool _create(layoutmgr *lmgr, void *data) @@ -123,6 +212,9 @@ static void _destroy(void *layout_data) priv = layout_data; + if (priv->channel_info) + tv_channel_del_info(priv->channel_info); + evas_object_del(priv->layout); free(priv); } @@ -136,8 +228,6 @@ static void _show(void *layout_data) priv = layout_data; - _update_channel_info(priv); - elm_object_content_set(priv->base, priv->layout); evas_object_show(priv->layout); } @@ -155,33 +245,63 @@ static void _hide(void *layout_data) elm_object_content_unset(priv->base); } -static void _update(void *layout_data, int update_type, void *data) +static void _update(void *layout_data, int type, void *data) { - Evas_Event_Key_Down *ev = data; struct _priv *priv; int r; - if (!layout_data || !ev) { + if (!layout_data) { _ERR("failed to get layout_data and ev"); return; } priv = layout_data; - if (!strcmp(ev->keyname, KEY_CHANNELUP) || - !strcmp(ev->keyname, KEY_CHANNELUP_REMOTE)) { - r = tv_channel_next(); - if (r < 0) - _ERR("failed to tune next channel"); - - _update_channel_info(priv); - } else if (!strcmp(ev->keyname, KEY_CHANNELDOWN) || - !strcmp(ev->keyname, KEY_CHANNELDOWN_REMOTE)) { - r = tv_channel_prev(); - if (r < 0) - _ERR("failed to tune next channel"); - - _update_channel_info(priv); + if (type == UPDATE_TYPE_INPUT_KEY_DOWN) { + Evas_Event_Key_Down *ev = data; + + if (!ev) { + _ERR("failed to get ev"); + return; + } + + if (!strcmp(ev->keyname, KEY_CHANNELUP) || + !strcmp(ev->keyname, KEY_CHANNELUP_REMOTE)) { + r = _set_next_channel(priv, CHANNEL_NEXT); + if (r < 0) + _ERR("failed to set next channel"); + else + _update_channel_info(priv); + } else if (!strcmp(ev->keyname, KEY_CHANNELDOWN) || + !strcmp(ev->keyname, KEY_CHANNELDOWN_REMOTE)) { + r = _set_next_channel(priv, CHANNEL_PREV); + if (r < 0) + _ERR("failed to set prev channel"); + else + _update_channel_info(priv); + } + } else if (type == UPDATE_TYPE_INPUT_KEY_UP) { + Evas_Event_Key_Up *ev = data; + + if (!ev) { + _ERR("failed to get ev"); + return; + } + + if (!strcmp(ev->keyname, KEY_CHANNELUP) || + !strcmp(ev->keyname, KEY_CHANNELUP_REMOTE) || + !strcmp(ev->keyname, KEY_CHANNELDOWN) || + !strcmp(ev->keyname, KEY_CHANNELDOWN_REMOTE)) { + if (!priv->channel_info) { + _ERR("failed to get channel info"); + return; + } + + r = tv_channel_tune_with_service_id( + priv->channel_info->service_id); + if (r < 0) + _ERR("failed to tune next channel"); + } } } diff --git a/src/main.c b/src/main.c index 5b35c61..c8791c4 100644 --- a/src/main.c +++ b/src/main.c @@ -62,7 +62,26 @@ static void _key_down_cb(int id, void *data, Evas *e, Evas_Object *obj, if (!strcmp(ev->keyname, g_kmap[i].key[j])) { viewmgr_show_view(g_kmap[i].view); viewmgr_update_view(g_kmap[i].view, - UPDATE_TYPE_INPUT, ev); + UPDATE_TYPE_INPUT_KEY_DOWN, ev); + return; + } + j++; + } + } +} + +static void _key_up_cb(int id, void *data, Evas *e, Evas_Object *obj, + Evas_Event_Key_Up *ev) +{ + size_t i, j; + + for (i = 0; i < sizeof(g_kmap) / sizeof(*g_kmap); i++) { + j = 0; + while (g_kmap[i].key[j]) { + if (!strcmp(ev->keyname, g_kmap[i].key[j])) { + viewmgr_show_view(g_kmap[i].view); + viewmgr_update_view(g_kmap[i].view, + UPDATE_TYPE_INPUT_KEY_UP, ev); return; } j++; @@ -72,6 +91,7 @@ static void _key_down_cb(int id, void *data, Evas *e, Evas_Object *obj, static input_handler key_handler = { .key_down = _key_down_cb, + .key_up = _key_up_cb, }; static Evas_Object *_add_win(const char *name) @@ -192,6 +212,14 @@ static bool _create(void *data) return false; } + if (!viewmgr_create(win)) { + _ERR("failed to initialize viewmgr"); + evas_object_del(win); + return false; + } + + viewmgr_add_view(view_channelinfo_get_vclass(), NULL); + r = tv_create(); if (r < 0) { _ERR("Create TV failed"); @@ -206,14 +234,6 @@ static bool _create(void *data) return false; } - if (!viewmgr_create(win)) { - _ERR("failed to initialize viewmgr"); - evas_object_del(win); - return false; - } - - viewmgr_add_view(view_channelinfo_get_vclass(), NULL); - ad->win = win; tv_signal_cb_set(_tv_signal_cb, ad); @@ -232,14 +252,14 @@ static void _terminate(void *data) ad = data; - tv_destroy(); + if (ad->win) { + tv_destroy(); - inputmgr_remove_callback(ad->win, &key_handler); + inputmgr_remove_callback(ad->win, &key_handler); - viewmgr_remove_view(VIEW_CHANNELINFO); - viewmgr_destroy(); + viewmgr_remove_view(VIEW_CHANNELINFO); + viewmgr_destroy(); - if (ad->win) { evas_object_del(ad->win); ad->win = NULL; } diff --git a/src/tv.c b/src/tv.c index abacbe9..fff8b6d 100644 --- a/src/tv.c +++ b/src/tv.c @@ -90,6 +90,33 @@ static struct tv_channel_info *_tv_channel_get_info(TvServiceChannel *channel) } /** + * Clones the tv_channel_info. + * + * @param channel_info tv_channel_info pointer to be cloned + * @return Channel information, or NULL if fails + */ +const struct tv_channel_info *tv_channel_clone_info( + const struct tv_channel_info *channel_info) +{ + struct tv_channel_info *new_channel_info = NULL; + + if (!channel_info) { + _ERR("failed to get channel info"); + return NULL; + } + + new_channel_info = calloc(1, sizeof(*channel_info)); + if (!new_channel_info) { + _ERR("failed to calloc channel info"); + return NULL; + } + + memcpy(new_channel_info, channel_info, sizeof(*new_channel_info)); + + return new_channel_info; +} + +/** * Frees the tv_channel_info. * * @param channel_info tv_channel_info pointer to be freed diff --git a/src/view_channelinfo.c b/src/view_channelinfo.c index bcd8488..9d1c3a2 100644 --- a/src/view_channelinfo.c +++ b/src/view_channelinfo.c @@ -363,7 +363,6 @@ static void _destroy(void *view_data) static void _update(void *view_data, int type, void *data) { struct _priv *priv; - Evas_Event_Key_Down *ev; if (!view_data) { _ERR("failed to get view data"); @@ -381,8 +380,9 @@ static void _update(void *view_data, int type, void *data) _stop_hide_timer(priv); break; } - } else if (type == UPDATE_TYPE_INPUT) { - ev = data; + } else if (type == UPDATE_TYPE_INPUT_KEY_DOWN) { + Evas_Event_Key_Down *ev = data; + if (!ev) { _ERR("failed to get ev"); return; @@ -401,7 +401,23 @@ static void _update(void *view_data, int type, void *data) !strcmp(ev->keyname, KEY_CHANNELDOWN_REMOTE)) { _set_current_layout(priv, LAYOUT_CHANNELINFO_LIST); layoutmgr_update_layout(priv->lmgr, - LAYOUT_CHANNELINFO_LIST, 0, ev); + LAYOUT_CHANNELINFO_LIST, type, ev); + } + } else if (type == UPDATE_TYPE_INPUT_KEY_UP) { + Evas_Event_Key_Up *ev = data; + + if (!ev) { + _ERR("failed to get ev"); + return; + } + + if (!strcmp(ev->keyname, KEY_CHANNELUP) || + !strcmp(ev->keyname, KEY_CHANNELUP_REMOTE) || + !strcmp(ev->keyname, KEY_CHANNELDOWN) || + !strcmp(ev->keyname, KEY_CHANNELDOWN_REMOTE)) { + _set_current_layout(priv, LAYOUT_CHANNELINFO_LIST); + layoutmgr_update_layout(priv->lmgr, + LAYOUT_CHANNELINFO_LIST, type, ev); } } }