From b13602bd7bdb4617198d3b98d1339945febfb1ad Mon Sep 17 00:00:00 2001 From: "jinwoo.shin" Date: Mon, 6 Jul 2015 10:49:04 +0900 Subject: [PATCH 01/16] Add channelinfo search layout Change-Id: I8c823e6e12c468a89f0e89ddb4cd9ac861cb16fe Signed-off-by: jinwoo.shin --- CMakeLists.txt | 1 + data/view/channelinfo.edc | 11 +- include/define.h | 1 + include/layout_channelinfo_search.h | 22 ++++ src/layout_channelinfo.c | 7 +- src/layout_channelinfo_list.c | 3 +- src/layout_channelinfo_search.c | 208 ++++++++++++++++++++++++++++++++++++ src/view_channelinfo.c | 4 + 8 files changed, 249 insertions(+), 8 deletions(-) create mode 100644 include/layout_channelinfo_search.h create mode 100644 src/layout_channelinfo_search.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 58ce3f2..9bdcd5b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,6 +42,7 @@ SET(SRCS src/main.c src/view_channelinfo.c src/layout_channelinfo.c src/layout_channelinfo_list.c + src/layout_channelinfo_search.c src/util.c src/tv_service.c) diff --git a/data/view/channelinfo.edc b/data/view/channelinfo.edc index 4d8bafe..b97ee55 100644 --- a/data/view/channelinfo.edc +++ b/data/view/channelinfo.edc @@ -25,8 +25,8 @@ group { scale, 1; description { state, "default" 0.0; - rel1.relative, 1.0 0.5; - rel2.relative, 1.0 0.5; + rel1.relative, 1.0 0.0; + rel2.relative, 1.0 1.0; min, 536 0; align, 1.0 0.5; fixed, 1 0; @@ -48,6 +48,8 @@ group { scale, 1; description { state, "default" 0.0; + rel1.relative, 0.0 0.5; + rel2.relative, 0.0 0.5; min, 536 486; align, 0.0 0.5; fixed, 1 1; @@ -224,9 +226,10 @@ group { scale, 1; description { state, "default" 0.0; + rel1.relative, 0.0 0.5; + rel2.relative, 0.0 0.5; min, 536 174; align, 0.0 0.5; - fixed, 1 1; } description { state, "focused" 0.0; @@ -454,7 +457,7 @@ group { description { state, "default" 0.0; min, 536 70; - align, 1.0 0.5; + align, 0.0 0.0; fixed, 1 1; visible, 0; } diff --git a/include/define.h b/include/define.h index 83dd802..8b4760f 100644 --- a/include/define.h +++ b/include/define.h @@ -47,6 +47,7 @@ #define VIEW_CHANNELINFO "VIEW_CHANNELINFO" #define LAYOUT_CHANNELINFO "LAYOUT_CHANNELINFO" #define LAYOUT_CHANNELINFO_LIST "LAYOUT_CHANNELINFO_LIST" +#define LAYOUT_CHANNELINFO_SEARCH "LAYOUT_CHANNELINFO_SEARCH" #define GRP_VIEW_CHANNELINFO "grp.view.channelinfo" diff --git a/include/layout_channelinfo_search.h b/include/layout_channelinfo_search.h new file mode 100644 index 0000000..f2507c3 --- /dev/null +++ b/include/layout_channelinfo_search.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __LAYOUT_CHANNELINFO_SEARCH_H__ +#define __LAYOUT_CHANNELINFO_SEARCH_H__ + +layout_class *layout_channelinfo_search_get_lclass(void); + +#endif /* __LAYOUT_CHANNELINFO_SEARCH_H__*/ diff --git a/src/layout_channelinfo.c b/src/layout_channelinfo.c index 345adb7..00a58e0 100644 --- a/src/layout_channelinfo.c +++ b/src/layout_channelinfo.c @@ -67,12 +67,9 @@ static bool _create(layoutmgr *lmgr, void *data) _ERR("failed to create layout"); return false; } - if (!elm_layout_file_set(layout, EDJEFILE, GRP_CHANNELINFO)) goto error; - elm_object_content_set(base, layout); - priv->base = base; priv->layout = layout; priv->lmgr = lmgr; @@ -118,7 +115,10 @@ static void _show(void *layout_data) _update_channel_info(priv); + elm_object_content_set(priv->base, priv->layout); evas_object_show(priv->layout); + + elm_object_focus_allow_set(priv->base, EINA_TRUE); } static void _hide(void *layout_data) @@ -131,6 +131,7 @@ static void _hide(void *layout_data) priv = layout_data; evas_object_hide(priv->layout); + elm_object_content_unset(priv->base); } static void _update(void *layout_data, int update_type, void *data) diff --git a/src/layout_channelinfo_list.c b/src/layout_channelinfo_list.c index eb37091..61c85f1 100644 --- a/src/layout_channelinfo_list.c +++ b/src/layout_channelinfo_list.c @@ -70,7 +70,6 @@ static bool _create(layoutmgr *lmgr, void *data) } if (!elm_layout_file_set(priv->layout, EDJEFILE, GRP_CHANNELINFO_LIST)) goto error; - elm_object_content_set(priv->base, priv->layout); priv->next_channel = util_add_layout(priv->layout, GRP_CHANNELINFO_SIMPLE); @@ -139,6 +138,7 @@ static void _show(void *layout_data) _update_channel_info(priv); + elm_object_content_set(priv->base, priv->layout); evas_object_show(priv->layout); } @@ -152,6 +152,7 @@ static void _hide(void *layout_data) priv = layout_data; evas_object_hide(priv->layout); + elm_object_content_unset(priv->base); } static void _update(void *layout_data, int update_type, void *data) diff --git a/src/layout_channelinfo_search.c b/src/layout_channelinfo_search.c new file mode 100644 index 0000000..315f35d --- /dev/null +++ b/src/layout_channelinfo_search.c @@ -0,0 +1,208 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +#include +#include +#include +#include +#include + +#include "define.h" +#include "util.h" +#include "tv.h" +#include "view_channelinfo.h" + +#define DIVIDER_WIDTH 536 +#define DIVIDER_HEIGHT 1 +#define DIVIDER_COLOR_R 0 +#define DIVIDER_COLOR_G 0 +#define DIVIDER_COLOR_B 0 +#define DIVIDER_COLOR_A (255 * 0.1) + +struct _priv { + Evas_Object *base; + Evas_Object *scroll; + Evas_Object *box; + + layoutmgr *lmgr; + Eina_List *channel_list; +}; + +static void _load_channel_list(struct _priv *priv, Eina_List *channel_list) +{ + Evas_Object *ly, *divider; + Evas *e; + Eina_List *l; + const struct tv_channel_info *channel_info; + int r; + int current_service; + + r = tv_get_current_service_id(¤t_service); + if (r < 0) + current_service = -1; + + e = evas_object_evas_get(priv->base); + + divider = evas_object_rectangle_add(e); + evas_object_color_set(divider, DIVIDER_COLOR_R, + DIVIDER_COLOR_G, DIVIDER_COLOR_B, DIVIDER_COLOR_A); + evas_object_size_hint_min_set(divider, + DIVIDER_WIDTH, DIVIDER_HEIGHT); + evas_object_show(divider); + + elm_box_clear(priv->box); + + EINA_LIST_FOREACH(channel_list, l, channel_info) { + if (!channel_info->remembered) + continue; + + ly = util_add_layout(priv->box, GRP_CHANNELINFO); + if (!ly) + continue; + elm_object_focus_allow_set(ly, EINA_TRUE); + draw_channel_info(ly, channel_info); + + elm_box_pack_end(priv->box, ly); + + if (eina_list_next(l)) + elm_box_pack_end(priv->box, divider); + } +} + +static void _update_channel_list(struct _priv *priv) +{ + if (!priv) { + _ERR("failed to get priv"); + return; + } + + if (priv->channel_list) + tv_channel_del_list(priv->channel_list); + + priv->channel_list = tv_channel_get_list(); + if (!priv->channel_list) { + _ERR("failed to get channel list"); + return; + } + + _load_channel_list(priv, priv->channel_list); +} + +static bool _create(layoutmgr *lmgr, void *data) +{ + struct _priv *priv; + + priv = calloc(1, sizeof(*priv)); + if (!priv) { + _ERR("failed to allocate priv"); + return false; + } + + priv->base = layoutmgr_get_base(lmgr); + + priv->scroll = elm_scroller_add(priv->base); + if (!priv->scroll) { + _ERR("failed to create scroll"); + goto error; + } + evas_object_size_hint_weight_set(priv->scroll, + EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + + priv->box = util_add_box(priv->scroll, false); + if (!priv->box) { + _ERR("failed to create box"); + goto error; + } + elm_box_align_set(priv->box, 0.0, 0.5); + elm_box_padding_set(priv->box, 0, DIVIDER_HEIGHT); + evas_object_color_set(priv->box, DIVIDER_COLOR_R, + DIVIDER_COLOR_G, DIVIDER_COLOR_B, DIVIDER_COLOR_A); + + priv->lmgr = lmgr; + + layoutmgr_set_layout_data(lmgr, LAYOUT_CHANNELINFO_SEARCH, priv); + + return true; + +error: + evas_object_del(priv->scroll); + evas_object_del(priv->box); + free(priv); + + return false; +} + +static void _destroy(void *layout_data) +{ + struct _priv *priv; + + if (!layout_data) + return; + + priv = layout_data; + + if (priv->channel_list) + tv_channel_del_list(priv->channel_list); + + evas_object_del(priv->scroll); + free(priv); +} + +static void _show(void *layout_data) +{ + struct _priv *priv; + + if (!layout_data) + return; + + priv = layout_data; + + _update_channel_list(priv); + + elm_object_content_set(priv->base, priv->scroll); + evas_object_show(priv->scroll); +} + +static void _hide(void *layout_data) +{ + struct _priv *priv; + + if (!layout_data) + return; + + priv = layout_data; + + elm_object_content_unset(priv->base); + evas_object_hide(priv->scroll); +} + +static void _update(void *layout_data, int update_type, void *data) +{ +} + +static layout_class lclass = { + .layout_id = LAYOUT_CHANNELINFO_SEARCH, + .create = _create, + .show = _show, + .hide = _hide, + .destroy = _destroy, + .update = _update, +}; + +layout_class *layout_channelinfo_search_get_lclass(void) +{ + return &lclass; +} diff --git a/src/view_channelinfo.c b/src/view_channelinfo.c index aab1685..cf5396c 100644 --- a/src/view_channelinfo.c +++ b/src/view_channelinfo.c @@ -24,6 +24,7 @@ #include "tv.h" #include "layout_channelinfo.h" #include "layout_channelinfo_list.h" +#include "layout_channelinfo_search.h" #define HIDE_DUR 10.0 #define BUF_MAX 128 @@ -274,6 +275,8 @@ static Evas_Object *_create(Evas_Object *win, void *data) layoutmgr_add_layout(priv->lmgr, layout_channelinfo_get_lclass(), NULL); layoutmgr_add_layout(priv->lmgr, layout_channelinfo_list_get_lclass(), NULL); + layoutmgr_add_layout(priv->lmgr, + layout_channelinfo_search_get_lclass(), NULL); viewmgr_set_view_data(VIEW_CHANNELINFO, priv); @@ -323,6 +326,7 @@ static void _destroy(void *view_data) layoutmgr_remove_layout(priv->lmgr, LAYOUT_CHANNELINFO); layoutmgr_remove_layout(priv->lmgr, LAYOUT_CHANNELINFO_LIST); + layoutmgr_remove_layout(priv->lmgr, LAYOUT_CHANNELINFO_SEARCH); layoutmgr_destroy(priv->lmgr); evas_object_del(priv->base); -- 2.7.4 From 10bd6f2814ee5a36d8e10bc0df3bbca4a5c4ca70 Mon Sep 17 00:00:00 2001 From: "jinwoo.shin" Date: Mon, 6 Jul 2015 16:33:07 +0900 Subject: [PATCH 02/16] Add key event support Change-Id: Ibca35a28730f4af9b355ec167ce36b9bece24983 Signed-off-by: jinwoo.shin --- include/view_channelinfo.h | 5 +++ src/layout_channelinfo_list.c | 26 ++++++++++++++ src/layout_channelinfo_search.c | 4 --- src/main.c | 18 +++++----- src/view_channelinfo.c | 79 +++++++++++++++++++++++++++++++++-------- 5 files changed, 106 insertions(+), 26 deletions(-) diff --git a/include/view_channelinfo.h b/include/view_channelinfo.h index f9e5068..6ced573 100644 --- a/include/view_channelinfo.h +++ b/include/view_channelinfo.h @@ -17,6 +17,11 @@ #ifndef __LIVETV_VIEW_CHANNELINFO_H__ #define __LIVETV_VIEW_CHANNELINFO_H__ +enum _update_type { + UPDATE_TYPE_TIMER, + UPDATE_TYPE_INPUT, +}; + void draw_channel_info(Evas_Object *obj, const struct tv_channel_info *channel_info); view_class *view_channelinfo_get_vclass(void); diff --git a/src/layout_channelinfo_list.c b/src/layout_channelinfo_list.c index 61c85f1..03249a5 100644 --- a/src/layout_channelinfo_list.c +++ b/src/layout_channelinfo_list.c @@ -157,6 +157,32 @@ static void _hide(void *layout_data) static void _update(void *layout_data, int update_type, void *data) { + Evas_Event_Key_Down *ev = data; + struct _priv *priv; + int r; + + if (!layout_data || !ev) { + _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); + } } static layout_class lclass = { diff --git a/src/layout_channelinfo_search.c b/src/layout_channelinfo_search.c index 315f35d..ba04001 100644 --- a/src/layout_channelinfo_search.c +++ b/src/layout_channelinfo_search.c @@ -74,7 +74,6 @@ static void _load_channel_list(struct _priv *priv, Eina_List *channel_list) continue; elm_object_focus_allow_set(ly, EINA_TRUE); draw_channel_info(ly, channel_info); - elm_box_pack_end(priv->box, ly); if (eina_list_next(l)) @@ -127,9 +126,6 @@ static bool _create(layoutmgr *lmgr, void *data) goto error; } elm_box_align_set(priv->box, 0.0, 0.5); - elm_box_padding_set(priv->box, 0, DIVIDER_HEIGHT); - evas_object_color_set(priv->box, DIVIDER_COLOR_R, - DIVIDER_COLOR_G, DIVIDER_COLOR_B, DIVIDER_COLOR_A); priv->lmgr = lmgr; diff --git a/src/main.c b/src/main.c index e3acd73..5b35c61 100644 --- a/src/main.c +++ b/src/main.c @@ -36,22 +36,23 @@ struct _appdata { }; struct key_map { - const char *view; - const char *key[KEY_MAX]; + const char *view; + const char *key[KEY_MAX]; }; static struct key_map g_kmap[] = { { VIEW_CHANNELINFO, { - KEY_ENTER, KEY_ENTER_REMOTE, KEY_CHANNELUP, - KEY_CHANNELUP_REMOTE, KEY_CHANNELDOWN, KEY_CHANNELDOWN_REMOTE + KEY_ENTER, KEY_ENTER_REMOTE, + KEY_CHANNELUP, KEY_CHANNELUP_REMOTE, + KEY_CHANNELDOWN, KEY_CHANNELDOWN_REMOTE } }, }; -static void _key_up_cb(int id, void *data, Evas *e, Evas_Object *obj, - Evas_Event_Key_Up *ev) +static void _key_down_cb(int id, void *data, Evas *e, Evas_Object *obj, + Evas_Event_Key_Down *ev) { size_t i, j; @@ -60,7 +61,8 @@ static void _key_up_cb(int id, void *data, Evas *e, Evas_Object *obj, 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, ev); + viewmgr_update_view(g_kmap[i].view, + UPDATE_TYPE_INPUT, ev); return; } j++; @@ -69,7 +71,7 @@ static void _key_up_cb(int id, void *data, Evas *e, Evas_Object *obj, } static input_handler key_handler = { - .key_up = _key_up_cb, + .key_down = _key_down_cb, }; static Evas_Object *_add_win(const char *name) diff --git a/src/view_channelinfo.c b/src/view_channelinfo.c index cf5396c..bcd8488 100644 --- a/src/view_channelinfo.c +++ b/src/view_channelinfo.c @@ -22,6 +22,7 @@ #include "define.h" #include "tv.h" +#include "view_channelinfo.h" #include "layout_channelinfo.h" #include "layout_channelinfo_list.h" #include "layout_channelinfo_search.h" @@ -30,7 +31,7 @@ #define BUF_MAX 128 #define STATUS_BOX_PADDING 10 -enum _update_type { +enum _update_op { START_HIDE_TIMER, STOP_HIDE_TIMER }; @@ -38,6 +39,7 @@ enum _update_type { struct _priv { Evas_Object *base; Ecore_Timer *hide_timer; + const char *current_layout; layoutmgr *lmgr; }; @@ -204,7 +206,8 @@ static void _tv_program_cb(Eina_List *prog_list, void *data) else _ERR("failed to get tv_program_info"); - viewmgr_update_view(VIEW_CHANNELINFO, START_HIDE_TIMER); + viewmgr_update_view(VIEW_CHANNELINFO, + UPDATE_TYPE_TIMER, START_HIDE_TIMER); } void draw_channel_info(Evas_Object *obj, @@ -224,7 +227,8 @@ void draw_channel_info(Evas_Object *obj, if (r < 0) current_service = -1; - viewmgr_update_view(VIEW_CHANNELINFO, (void *) STOP_HIDE_TIMER); + viewmgr_update_view(VIEW_CHANNELINFO, + UPDATE_TYPE_TIMER, (void *)STOP_HIDE_TIMER); _load_channel_text(obj, channel_info); _pack_icon_box(obj, channel_info); @@ -241,7 +245,29 @@ void draw_channel_info(Evas_Object *obj, if (r < 0) viewmgr_update_view(VIEW_CHANNELINFO, - (void *) START_HIDE_TIMER); + UPDATE_TYPE_TIMER, START_HIDE_TIMER); +} + +static void _hide_current_layout(struct _priv *priv) +{ + if (!priv->current_layout) + return; + + layoutmgr_hide_layout(priv->lmgr, priv->current_layout); + priv->current_layout = NULL; +} + +static void _set_current_layout(struct _priv *priv, const char *layout_id) +{ + if (priv->current_layout && layout_id && + !strcmp(priv->current_layout, layout_id)) + return; + + if (priv->current_layout) + layoutmgr_hide_layout(priv->lmgr, priv->current_layout); + + layoutmgr_show_layout(priv->lmgr, layout_id); + priv->current_layout = layout_id; } static Evas_Object *_create(Evas_Object *win, void *data) @@ -294,8 +320,6 @@ static void _show(void *view_data) priv = view_data; - layoutmgr_show_layout(priv->lmgr, LAYOUT_CHANNELINFO); - evas_object_show(priv->base); } @@ -310,6 +334,8 @@ static void _hide(void *view_data) priv = view_data; + _hide_current_layout(priv); + evas_object_hide(priv->base); } @@ -334,9 +360,10 @@ static void _destroy(void *view_data) free(priv); } -static void _update(void *view_data, void *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"); @@ -345,13 +372,37 @@ static void _update(void *view_data, void *data) priv = view_data; - switch ((int) data) { - case START_HIDE_TIMER: - _start_hide_timer(priv); - break; - case STOP_HIDE_TIMER: - _stop_hide_timer(priv); - break; + if (type == UPDATE_TYPE_TIMER) { + switch ((int) data) { + case START_HIDE_TIMER: + _start_hide_timer(priv); + break; + case STOP_HIDE_TIMER: + _stop_hide_timer(priv); + break; + } + } else if (type == UPDATE_TYPE_INPUT) { + ev = data; + if (!ev) { + _ERR("failed to get ev"); + return; + } + + if (!strcmp(ev->keyname, KEY_ENTER) || + !strcmp(ev->keyname, KEY_ENTER_REMOTE)) { + if (!priv->current_layout) + _set_current_layout(priv, LAYOUT_CHANNELINFO); + else + _set_current_layout(priv, + LAYOUT_CHANNELINFO_SEARCH); + } else 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, 0, ev); + } } } -- 2.7.4 From 183923c7714edec234ad2f944492ffb48d83bdfc Mon Sep 17 00:00:00 2001 From: "jinwoo.shin" Date: Fri, 10 Jul 2015 19:58:27 +0900 Subject: [PATCH 03/16] Add channel next/prev event Change-Id: Ie8a3182aa1db8d16bb0d648b418324bda1d56994 Signed-off-by: jinwoo.shin --- data/view/channelinfo.edc | 18 +++++ include/tv.h | 5 +- include/view_channelinfo.h | 3 +- src/layout_channelinfo_list.c | 170 +++++++++++++++++++++++++++++++++++------- src/main.c | 48 ++++++++---- src/tv.c | 27 +++++++ src/view_channelinfo.c | 24 +++++- 7 files changed, 250 insertions(+), 45 deletions(-) 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); } } } -- 2.7.4 From 7a8d96e57adaa93c25be136c8ae810a773c9b766 Mon Sep 17 00:00:00 2001 From: "jinwoo.shin" Date: Tue, 14 Jul 2015 14:14:48 +0900 Subject: [PATCH 04/16] Add focus related handlings Change-Id: Ib4023446f1778d0f32e4d7210f2a50ea7519f1eb Signed-off-by: jinwoo.shin --- src/layout_channelinfo_search.c | 14 +++++++++++++- src/main.c | 2 +- src/view_channelinfo.c | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 2 deletions(-) diff --git a/src/layout_channelinfo_search.c b/src/layout_channelinfo_search.c index ba04001..3a3aac4 100644 --- a/src/layout_channelinfo_search.c +++ b/src/layout_channelinfo_search.c @@ -43,7 +43,7 @@ struct _priv { static void _load_channel_list(struct _priv *priv, Eina_List *channel_list) { - Evas_Object *ly, *divider; + Evas_Object *ly, *divider, *first; Evas *e; Eina_List *l; const struct tv_channel_info *channel_info; @@ -65,6 +65,7 @@ static void _load_channel_list(struct _priv *priv, Eina_List *channel_list) elm_box_clear(priv->box); + first = NULL; EINA_LIST_FOREACH(channel_list, l, channel_info) { if (!channel_info->remembered) continue; @@ -78,6 +79,17 @@ static void _load_channel_list(struct _priv *priv, Eina_List *channel_list) if (eina_list_next(l)) elm_box_pack_end(priv->box, divider); + + if (channel_info->service_id == current_service) + elm_object_focus_set(ly, EINA_TRUE); + + if (!first) + first = ly; + } + + if (first && ly) { + elm_object_focus_next_object_set(first, ly, ELM_FOCUS_UP); + elm_object_focus_next_object_set(ly, first, ELM_FOCUS_DOWN); } } diff --git a/src/main.c b/src/main.c index c8791c4..b67228b 100644 --- a/src/main.c +++ b/src/main.c @@ -104,7 +104,7 @@ static Evas_Object *_add_win(const char *name) return NULL; } elm_win_alpha_set(win, EINA_FALSE); - elm_win_focus_highlight_enabled_set(win, EINA_TRUE); + elm_win_focus_highlight_enabled_set(win, EINA_FALSE); elm_win_focus_highlight_style_set(win, "invisible"); evas_object_show(win); diff --git a/src/view_channelinfo.c b/src/view_channelinfo.c index 9d1c3a2..6e4296a 100644 --- a/src/view_channelinfo.c +++ b/src/view_channelinfo.c @@ -44,6 +44,33 @@ struct _priv { layoutmgr *lmgr; }; +static void _update(void *view_data, int type, void *data); + +static void _key_down_cb(int id, void *data, Evas *e, Evas_Object *obj, + Evas_Event_Key_Down *ev) +{ + _update(data, UPDATE_TYPE_INPUT_KEY_DOWN, ev); +} + +static void _key_up_cb(int id, void *data, Evas *e, Evas_Object *obj, + Evas_Event_Key_Up *ev) +{ + _update(data, UPDATE_TYPE_INPUT_KEY_UP, ev); +} + +void _mouse_move_cb(int id, void *data, Evas *e, Evas_Object *obj, + Evas_Event_Mouse_Move *ev) +{ + viewmgr_update_view(VIEW_CHANNELINFO, + UPDATE_TYPE_TIMER, START_HIDE_TIMER); +} + +static input_handler key_handler = { + .key_down = _key_down_cb, + .key_up = _key_up_cb, + .mouse_move = _mouse_move_cb, +}; + static int _get_program_time(char *buf, int buf_len, time_t start_time, time_t end_time) { @@ -306,6 +333,8 @@ static Evas_Object *_create(Evas_Object *win, void *data) viewmgr_set_view_data(VIEW_CHANNELINFO, priv); + inputmgr_add_callback(priv->base, 0, &key_handler, priv); + return priv->base; } @@ -355,6 +384,8 @@ static void _destroy(void *view_data) layoutmgr_remove_layout(priv->lmgr, LAYOUT_CHANNELINFO_SEARCH); layoutmgr_destroy(priv->lmgr); + inputmgr_remove_callback(priv->base, &key_handler); + evas_object_del(priv->base); free(priv); @@ -402,6 +433,8 @@ static void _update(void *view_data, int type, void *data) _set_current_layout(priv, LAYOUT_CHANNELINFO_LIST); layoutmgr_update_layout(priv->lmgr, LAYOUT_CHANNELINFO_LIST, type, ev); + } else { + _start_hide_timer(priv); } } else if (type == UPDATE_TYPE_INPUT_KEY_UP) { Evas_Event_Key_Up *ev = data; @@ -418,6 +451,10 @@ static void _update(void *view_data, int type, void *data) _set_current_layout(priv, LAYOUT_CHANNELINFO_LIST); layoutmgr_update_layout(priv->lmgr, LAYOUT_CHANNELINFO_LIST, type, ev); + } else if (!strcmp(ev->keyname, KEY_BACK) || + !strcmp(ev->keyname, KEY_BACK_REMOTE) || + !strcmp(ev->keyname, KEY_EXIT)) { + viewmgr_hide_view(VIEW_CHANNELINFO); } } } -- 2.7.4 From 0bd985a4a5477c62a7d9fed3a50757678efdff48 Mon Sep 17 00:00:00 2001 From: "jinwoo.shin" Date: Tue, 14 Jul 2015 15:11:39 +0900 Subject: [PATCH 05/16] Add tune channel function on search list layout Change-Id: I6455f12d54fc3cd9a69f72c8920ccbe285030695 Signed-off-by: jinwoo.shin --- src/layout_channelinfo_list.c | 5 ++++ src/layout_channelinfo_search.c | 63 ++++++++++++++++++++++++++++++++++------- 2 files changed, 58 insertions(+), 10 deletions(-) diff --git a/src/layout_channelinfo_list.c b/src/layout_channelinfo_list.c index 5d9ce51..1bcc741 100644 --- a/src/layout_channelinfo_list.c +++ b/src/layout_channelinfo_list.c @@ -241,6 +241,11 @@ static void _hide(void *layout_data) priv = layout_data; + if (priv->channel_info) { + tv_channel_del_info(priv->channel_info); + priv->channel_info = NULL; + } + evas_object_hide(priv->layout); elm_object_content_unset(priv->base); } diff --git a/src/layout_channelinfo_search.c b/src/layout_channelinfo_search.c index 3a3aac4..306a59c 100644 --- a/src/layout_channelinfo_search.c +++ b/src/layout_channelinfo_search.c @@ -38,7 +38,48 @@ struct _priv { Evas_Object *box; layoutmgr *lmgr; - Eina_List *channel_list; +}; + +static void _tune_channel(void *data) +{ + int service_id; + int r; + + if (!data) { + _ERR("failed to get data"); + return; + } + + service_id = (int) data; + if (service_id < 0) { + _ERR("failed to get service id"); + return; + } + + r = tv_channel_tune_with_service_id(service_id); + if (r < 0) + _ERR("failed to tune with service id"); + + viewmgr_hide_view(VIEW_CHANNELINFO); +} + +static void _key_down_cb(int id, void *data, Evas *e, Evas_Object *obj, + Evas_Event_Key_Down *ev) +{ + if (!strcmp(ev->keyname, KEY_ENTER) || + !strcmp(ev->keyname, KEY_ENTER_REMOTE)) + _tune_channel(data); +} + +void _mouse_down_cb(int id, void *data, Evas *e, Evas_Object *obj, + Evas_Event_Mouse_Down *ev) +{ + _tune_channel(data); +} + +static input_handler channel_handler = { + .key_down = _key_down_cb, + .mouse_down = _mouse_down_cb, }; static void _load_channel_list(struct _priv *priv, Eina_List *channel_list) @@ -66,6 +107,7 @@ static void _load_channel_list(struct _priv *priv, Eina_List *channel_list) elm_box_clear(priv->box); first = NULL; + ly = NULL; EINA_LIST_FOREACH(channel_list, l, channel_info) { if (!channel_info->remembered) continue; @@ -77,6 +119,9 @@ static void _load_channel_list(struct _priv *priv, Eina_List *channel_list) draw_channel_info(ly, channel_info); elm_box_pack_end(priv->box, ly); + inputmgr_add_callback(ly, 0, &channel_handler, + (void *) channel_info->service_id); + if (eina_list_next(l)) elm_box_pack_end(priv->box, divider); @@ -95,21 +140,22 @@ static void _load_channel_list(struct _priv *priv, Eina_List *channel_list) static void _update_channel_list(struct _priv *priv) { + Eina_List *channel_list; + if (!priv) { _ERR("failed to get priv"); return; } - if (priv->channel_list) - tv_channel_del_list(priv->channel_list); - - priv->channel_list = tv_channel_get_list(); - if (!priv->channel_list) { + channel_list = tv_channel_get_list(); + if (!channel_list) { _ERR("failed to get channel list"); return; } - _load_channel_list(priv, priv->channel_list); + _load_channel_list(priv, channel_list); + + tv_channel_del_list(channel_list); } static bool _create(layoutmgr *lmgr, void *data) @@ -162,9 +208,6 @@ static void _destroy(void *layout_data) priv = layout_data; - if (priv->channel_list) - tv_channel_del_list(priv->channel_list); - evas_object_del(priv->scroll); free(priv); } -- 2.7.4 From ad24aef8e4060765ab62c691f42a688ae9835ec1 Mon Sep 17 00:00:00 2001 From: "jinwoo.shin" Date: Wed, 15 Jul 2015 19:30:24 +0900 Subject: [PATCH 06/16] Add function to remove all event callbacks on the box Change-Id: I305f22f66feb41d82498e08b0ab119a572b8423b Signed-off-by: jinwoo.shin --- src/layout_channelinfo_search.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/layout_channelinfo_search.c b/src/layout_channelinfo_search.c index 306a59c..fbedb1d 100644 --- a/src/layout_channelinfo_search.c +++ b/src/layout_channelinfo_search.c @@ -71,7 +71,7 @@ static void _key_down_cb(int id, void *data, Evas *e, Evas_Object *obj, _tune_channel(data); } -void _mouse_down_cb(int id, void *data, Evas *e, Evas_Object *obj, +static void _mouse_down_cb(int id, void *data, Evas *e, Evas_Object *obj, Evas_Event_Mouse_Down *ev) { _tune_channel(data); @@ -82,6 +82,24 @@ static input_handler channel_handler = { .mouse_down = _mouse_down_cb, }; +static void _release_channel_handler(Evas_Object *obj) +{ + Eina_List *child, *l; + Evas_Object *ly; + + if (!obj) + return; + + child = elm_box_children_get(obj); + + EINA_LIST_FOREACH(child, l, ly) { + inputmgr_remove_callback(ly, &channel_handler); + } + + if (child) + eina_list_free(child); +} + static void _load_channel_list(struct _priv *priv, Eina_List *channel_list) { Evas_Object *ly, *divider, *first; @@ -104,6 +122,7 @@ static void _load_channel_list(struct _priv *priv, Eina_List *channel_list) DIVIDER_WIDTH, DIVIDER_HEIGHT); evas_object_show(divider); + _release_channel_handler(priv->box); elm_box_clear(priv->box); first = NULL; -- 2.7.4 From 5bd30ea364075b537e787115da47cd88f55873c2 Mon Sep 17 00:00:00 2001 From: "jinwoo.shin" Date: Wed, 15 Jul 2015 19:43:14 +0900 Subject: [PATCH 07/16] Add channel number view for tune by channel number Change-Id: Ied85abe9eacec42646914c348ac4045ed1e1dcfe Signed-off-by: jinwoo.shin --- CMakeLists.txt | 1 + data/live-tv.edc | 1 + data/view/channelnumber.edc | 327 +++++++++++++++++++++++ include/define.h | 10 + include/strings.h | 1 + include/{view_channelinfo.h => view.h} | 7 +- src/layout_channelinfo.c | 2 +- src/layout_channelinfo_list.c | 2 +- src/layout_channelinfo_search.c | 2 +- src/main.c | 13 +- src/view_channelinfo.c | 4 +- src/view_channelnumber.c | 459 +++++++++++++++++++++++++++++++++ 12 files changed, 820 insertions(+), 9 deletions(-) create mode 100644 data/view/channelnumber.edc rename include/{view_channelinfo.h => view.h} (86%) create mode 100644 src/view_channelnumber.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 9bdcd5b..9b42838 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -43,6 +43,7 @@ SET(SRCS src/main.c src/layout_channelinfo.c src/layout_channelinfo_list.c src/layout_channelinfo_search.c + src/view_channelnumber.c src/util.c src/tv_service.c) diff --git a/data/live-tv.edc b/data/live-tv.edc index 26d27bf..8a77133 100644 --- a/data/live-tv.edc +++ b/data/live-tv.edc @@ -18,4 +18,5 @@ collections { #include "view/channelinfo.edc" + #include "view/channelnumber.edc" } diff --git a/data/view/channelnumber.edc b/data/view/channelnumber.edc new file mode 100644 index 0000000..9892029 --- /dev/null +++ b/data/view/channelnumber.edc @@ -0,0 +1,327 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http,//www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "../../include/define.h" + +group { + name, GRP_VIEW_CHANNELNUMBER; + parts { + part { + name, "padding.channelnumber"; + type, SPACER; + description { + state, "default" 0.0; + rel1.relative, 0.0 0.0; + rel2.relative, 0.0 0.0; + align, 0.0 0.0; + min, 62 48; + fixed, 1 1; + } + } + part { + name, "part.channelnumber.info"; + type, RECT; + scale, 1; + description { + state, "default" 0.0; + rel1 { + to, "padding.channelnumber"; + relative, 1.0 1.0; + } + rel2 { + to, "padding.channelnumber"; + relative, 1.0 1.0; + } + min, 216 90; + align, 0.0 0.0; + fixed, 1 1; + visible, 0; + } + + part { + name, "padding.channelnumber.channel_prefix"; + type, SPACER; + scale, 1; + description { + state, "default" 0.0; + rel1.relative, 0.0 0.0; + rel2.relative, 0.0 0.0; + min, 0 34; + align, 0.0 0.0; + fixed, 1 1; + } + } + part { + name, "part.channelnumber.channel_prefix"; + type, TEXT; + scale, 1; + description { + state, "default" 0.0; + rel1 { + to, "padding.channelnumber.channel_prefix"; + relative, 0.0 1.0; + } + rel2 { + to, "padding.channelnumber.channel_prefix"; + relative, 0.0 1.0; + } + text { + font, FONT_LIGHT; + text, STR_CHANNEL_PREFIX; + size, 46; + align, 1.0 0.5; + min, 1 0; + ellipsis, -1; + } + color, COLOR_TEXT_TRANS; + min, 0 46; + align, 0.0 0.0; + fixed, 1 1; + } + } + part { + name, "padding.channelnumber.channel"; + type, SPACER; + scale, 1; + description { + state, "default" 0.0; + rel1 { + to_x, "part.channelnumber.channel_prefix"; + relative, 1.0 0.0; + } + rel2 { + to_x, "part.channelnumber.channel_prefix"; + relative, 1.0 1.0; + } + min, 26 0; + align, 0.0 0.0; + fixed, 1 1; + } + } + part { + name, PART_CHANNELNUMBER_NUMBER; + type, TEXT; + scale, 1; + description { + state, "default" 0.0; + rel1 { + to_x, "padding.channelnumber.channel"; + relative, 1.0 0.0; + } + rel2 { + to_x, "padding.channelnumber.channel"; + relative, 1.0 0.0; + } + text { + font, FONT_LIGHT; + size, 80; + align, 0.0 0.5; + min, 1 0; + ellipsis, -1; + } + color, COLOR_TEXT_TRANS; + min, 0 90; + align, 0.0 0.0; + fixed, 1 1; + } + } + } + part { + name, "padding.list"; + type, SPACER; + scale, 1; + description { + state, "default" 0.0; + rel1 { + to, "part.channelnumber.info"; + relative, 0.0 1.0; + } + rel2 { + to, "part.channelnumber.info"; + relative, 1.0 1.0; + } + min, 0 38; + align, 0.0 0.0; + fixed, 1 1; + } + } + part { + name, "bg.list.border"; + type, RECT; + scale, 1; + description { + state, "default" 0.0; + rel1 { + to, "padding.list"; + relative, 0.0 1.0; + } + rel2 { + to, "padding.list"; + relative, 1.0 1.0; + } + color, COLOR_OPTION_BORDER; + min, 216 224; + align, 0.0 0.0; + fixed, 1 1; + } + } + part { + name, "bg.list"; + type, RECT; + scale, 1; + description { + state, "default" 0.0; + rel1 { + to, "bg.list.border"; + relative, 0.5 0.5; + } + rel2 { + to, "bg.list.border"; + relative, 0.5 0.5; + } + color, COLOR_BG_NORMAL; + min, 214 222; + align, 0.5 0.5; + fixed, 1 1; + } + } + part { + name, PART_CHANNELNUMBER_LIST; + type, SWALLOW; + scale, 1; + description { + state, "default" 0.0; + rel1 { + to, "bg.list"; + relative, 0.0 0.0; + } + rel2 { + to, "bg.list"; + relative, 1.0 1.0; + } + align, 0.0 0.0; + fixed, 1 1; + } + } + } +} + +group { + name, GRP_CHANNELNUMBER_LIST_ITEM; + parts { + part { + name, "bg"; + type, RECT; + scale, 1; + description { + state, "default" 0.0; + color, COLOR_BG_NORMAL; + min, 216 56; + align, 0.0 0.0; + } + description { + state, "focused" 0.0; + inherit, "default" 0.0; + color, COLOR_BG_FOCUSED; + } + } + part { + name, "padding.left"; + type, SPACER; + scale, 1; + description { + state, "default" 0.0; + rel1 { + to, "bg"; + relative, 0.0 0.0; + } + rel2 { + to, "bg"; + relative, 0.0 1.0; + } + align, 0.0 0.0; + min, 30 0; + fixed, 1 1; + } + } + part { + name, "padding.right"; + type, SPACER; + scale, 1; + description { + state, "default" 0.0; + rel1 { + to, "bg"; + relative, 1.0 0.0; + } + rel2 { + to, "bg"; + relative, 1.0 1.0; + } + align, 1.0 0.0; + min, 30 0; + fixed, 1 1; + } + } + part { + name, PART_TEXT; + type, TEXT; + scale, 1; + description { + state, "default" 0.0; + rel1 { + to_x, "padding.left"; + relative, 1.0 0.0; + } + rel2 { + to_x, "padding.right"; + relative, 0.0 1.0; + } + text { + font, FONT_LIGHT; + size, 28; + align, 0.0 0.5; + } + color, COLOR_OPTION_TEXT_NORMAL; + align, 0.0 0.0; + } + description { + state, "focused" 0.0; + inherit, "default" 0.0; + color, COLOR_TEXT_FOCUSED; + } + } + } + programs { + program { + name, "focused"; + signal, SIGNAL_FOCUSED; + source, SOURCE_ELM; + action, STATE_SET "focused" 0.0; + target, "bg"; + target, PART_TEXT; + } + program { + name, "unfocused"; + signal, SIGNAL_UNFOCUSED; + source, SOURCE_ELM; + action, STATE_SET "default" 0.0; + target, "bg"; + target, PART_TEXT; + } + } +} + diff --git a/include/define.h b/include/define.h index 8b4760f..79000c3 100644 --- a/include/define.h +++ b/include/define.h @@ -22,6 +22,7 @@ #define KEY_SVCID "svcid" #define PART_CONTENT "elm.swallow.content" +#define PART_TEXT "elm.text" #define SOURCE_PROGRAM "program" #define SOURCE_ELM "elm" @@ -38,6 +39,9 @@ #define COLOR_TEXT_NORMAL 51 51 51 255 #define COLOR_TEXT_FOCUSED 255 255 255 255 #define COLOR_TEXT_TRANS 255 255 255 217 +#define COLOR_OPTION_TEXT_NORMAL 87 87 87 255 +#define COLOR_OPTION_TEXT_FOCUSED 255 255 255 255 +#define COLOR_OPTION_BORDER 154 154 154 255 #define IMG_LOCKED_NOR IMAGEDIR"ic_thumbnail_lock_01_nor.png" #define IMG_LOCKED_FOC IMAGEDIR"ic_thumbnail_lock_01_foc.png" @@ -63,4 +67,10 @@ #define PART_CHANNELINFO_TIME "part.channelinfo.time" #define PART_CHANNELINFO_STATUS "part.channelinfo.status" +#define VIEW_CHANNELNUMBER "VIEW_CHANNELNUMBER" +#define GRP_VIEW_CHANNELNUMBER "grp.view.channelnumber" +#define PART_CHANNELNUMBER_NUMBER "part.channelnumber.number" +#define PART_CHANNELNUMBER_LIST "part.channelnumber.list" +#define GRP_CHANNELNUMBER_LIST_ITEM "grp.channelnumber.list.item" + #endif /* __LIVETV_DEFINE_H__*/ diff --git a/include/strings.h b/include/strings.h index 026a670..cb65a19 100644 --- a/include/strings.h +++ b/include/strings.h @@ -19,5 +19,6 @@ #define STR_NOTITLE "No Information" #define STR_NOTIME "No Data" +#define STR_CHANNEL_PREFIX "CH." #endif /* __AIR_LIVETV_STRINGS_H__*/ diff --git a/include/view_channelinfo.h b/include/view.h similarity index 86% rename from include/view_channelinfo.h rename to include/view.h index 6637f1a..936f0fe 100644 --- a/include/view_channelinfo.h +++ b/include/view.h @@ -14,8 +14,8 @@ * limitations under the License. */ -#ifndef __LIVETV_VIEW_CHANNELINFO_H__ -#define __LIVETV_VIEW_CHANNELINFO_H__ +#ifndef __LIVETV_VIEW_H__ +#define __LIVETV_VIEW_H__ enum _update_type { UPDATE_TYPE_TIMER, @@ -25,6 +25,7 @@ enum _update_type { void draw_channel_info(Evas_Object *obj, const struct tv_channel_info *channel_info); +view_class *view_channelnumber_get_vclass(void); view_class *view_channelinfo_get_vclass(void); -#endif /* __LIVETV_VIEW_CHANNELINFO_H__*/ +#endif /* __LIVETV_VIEW_H__*/ diff --git a/src/layout_channelinfo.c b/src/layout_channelinfo.c index 00a58e0..5cdb323 100644 --- a/src/layout_channelinfo.c +++ b/src/layout_channelinfo.c @@ -22,7 +22,7 @@ #include "define.h" #include "tv.h" -#include "view_channelinfo.h" +#include "view.h" struct _priv { Evas_Object *base; diff --git a/src/layout_channelinfo_list.c b/src/layout_channelinfo_list.c index 1bcc741..a6ab0b9 100644 --- a/src/layout_channelinfo_list.c +++ b/src/layout_channelinfo_list.c @@ -23,7 +23,7 @@ #include "define.h" #include "util.h" #include "tv.h" -#include "view_channelinfo.h" +#include "view.h" enum _order { CHANNEL_NEXT, diff --git a/src/layout_channelinfo_search.c b/src/layout_channelinfo_search.c index fbedb1d..ef62aca 100644 --- a/src/layout_channelinfo_search.c +++ b/src/layout_channelinfo_search.c @@ -23,7 +23,7 @@ #include "define.h" #include "util.h" #include "tv.h" -#include "view_channelinfo.h" +#include "view.h" #define DIVIDER_WIDTH 536 #define DIVIDER_HEIGHT 1 diff --git a/src/main.c b/src/main.c index b67228b..9cdc317 100644 --- a/src/main.c +++ b/src/main.c @@ -22,7 +22,8 @@ #include "define.h" #include "tv.h" -#include "view_channelinfo.h" +#include "util.h" +#include "view.h" #define KEY_MAX 256 @@ -49,6 +50,14 @@ static struct key_map g_kmap[] = { KEY_CHANNELDOWN, KEY_CHANNELDOWN_REMOTE } }, + { + VIEW_CHANNELNUMBER, + { + KEY_0, KEY_1, KEY_2, KEY_3, + KEY_4, KEY_5, KEY_6, KEY_7, + KEY_8, KEY_9, KEY_MINUS + } + }, }; static void _key_down_cb(int id, void *data, Evas *e, Evas_Object *obj, @@ -219,6 +228,7 @@ static bool _create(void *data) } viewmgr_add_view(view_channelinfo_get_vclass(), NULL); + viewmgr_add_view(view_channelnumber_get_vclass(), NULL); r = tv_create(); if (r < 0) { @@ -258,6 +268,7 @@ static void _terminate(void *data) inputmgr_remove_callback(ad->win, &key_handler); viewmgr_remove_view(VIEW_CHANNELINFO); + viewmgr_remove_view(VIEW_CHANNELNUMBER); viewmgr_destroy(); evas_object_del(ad->win); diff --git a/src/view_channelinfo.c b/src/view_channelinfo.c index 6e4296a..86618e7 100644 --- a/src/view_channelinfo.c +++ b/src/view_channelinfo.c @@ -22,7 +22,7 @@ #include "define.h" #include "tv.h" -#include "view_channelinfo.h" +#include "view.h" #include "layout_channelinfo.h" #include "layout_channelinfo_list.h" #include "layout_channelinfo_search.h" @@ -58,7 +58,7 @@ static void _key_up_cb(int id, void *data, Evas *e, Evas_Object *obj, _update(data, UPDATE_TYPE_INPUT_KEY_UP, ev); } -void _mouse_move_cb(int id, void *data, Evas *e, Evas_Object *obj, +static void _mouse_move_cb(int id, void *data, Evas *e, Evas_Object *obj, Evas_Event_Mouse_Move *ev) { viewmgr_update_view(VIEW_CHANNELINFO, diff --git a/src/view_channelnumber.c b/src/view_channelnumber.c new file mode 100644 index 0000000..f478b31 --- /dev/null +++ b/src/view_channelnumber.c @@ -0,0 +1,459 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include + +#include "define.h" +#include "util.h" +#include "tv.h" +#include "view.h" + +#define HIDE_DUR 3.0 +#define BUF_MAX 128 + +struct _priv { + Evas_Object *base; + Evas_Object *list; + Ecore_Timer *hide_timer; + + int major; + int minor; +}; + +static void _update(void *view_data, int type, void *data); + +static void _key_down_cb(int id, void *data, Evas *e, Evas_Object *obj, + Evas_Event_Key_Down *ev) +{ + _update(data, UPDATE_TYPE_INPUT_KEY_DOWN, ev); +} + +static void _key_up_cb(int id, void *data, Evas *e, Evas_Object *obj, + Evas_Event_Key_Up *ev) +{ + _update(data, UPDATE_TYPE_INPUT_KEY_UP, ev); +} + +static void _mouse_move_cb(int id, void *data, Evas *e, Evas_Object *obj, + Evas_Event_Mouse_Move *ev) +{ + viewmgr_update_view(VIEW_CHANNELNUMBER, + UPDATE_TYPE_TIMER, 0); +} + +static input_handler key_handler = { + .key_down = _key_down_cb, + .key_up = _key_up_cb, + .mouse_move = _mouse_move_cb, +}; + +static Eina_Bool _hide_timer(void *data) +{ + struct _priv *priv; + int r; + + if (!data) + return ECORE_CALLBACK_CANCEL; + + priv = data; + + priv->hide_timer = NULL; + + r = tv_channel_direct_tune(priv->major, priv->minor); + if (r < 0) + _ERR("invalid channel"); + + viewmgr_hide_view(VIEW_CHANNELNUMBER); + + return ECORE_CALLBACK_CANCEL; +} + +static void _start_hide_timer(struct _priv *priv) +{ + if (priv->hide_timer) + ecore_timer_reset(priv->hide_timer); + else + priv->hide_timer = ecore_timer_add(HIDE_DUR, _hide_timer, priv); +} + +static void _stop_hide_timer(struct _priv *priv) +{ + if (priv->hide_timer) { + ecore_timer_del(priv->hide_timer); + priv->hide_timer = NULL; + } +} + +static void _tune_channel(void *data) +{ + int service_id; + int r; + + if (!data) { + _ERR("failed to get data"); + return; + } + + service_id = (int) data; + if (service_id < 0) { + _ERR("failed to get service id"); + return; + } + + r = tv_channel_tune_with_service_id(service_id); + if (r < 0) + _ERR("failed to tune with service id"); + + viewmgr_hide_view(VIEW_CHANNELNUMBER); +} + +static void _channel_key_down_cb(int id, void *data, Evas *e, Evas_Object *obj, + Evas_Event_Key_Down *ev) +{ + if (!strcmp(ev->keyname, KEY_ENTER) || + !strcmp(ev->keyname, KEY_ENTER_REMOTE)) + _tune_channel(data); +} + +static void _channel_mouse_down_cb(int id, void *data, Evas *e, + Evas_Object *obj, Evas_Event_Mouse_Down *ev) +{ + _tune_channel(data); +} + +static input_handler channel_handler = { + .key_down = _channel_key_down_cb, + .mouse_down = _channel_mouse_down_cb, +}; + +static void _release_channel_handler(Evas_Object *obj) +{ + Eina_List *child, *l; + Evas_Object *ly; + + if (!obj) + return; + + child = elm_box_children_get(obj); + + EINA_LIST_FOREACH(child, l, ly) { + inputmgr_remove_callback(ly, &channel_handler); + } + + if (child) + eina_list_free(child); +} + +static void _update_channel_list(struct _priv *priv) +{ + Evas_Object *ly, *first; + Eina_List *channel_list, *l; + const struct tv_channel_info *channel_info; + char buf[BUF_MAX]; + + channel_list = tv_channel_search_by_number(priv->major, priv->minor); + + _release_channel_handler(priv->list); + elm_box_clear(priv->list); + + first = NULL; + ly = NULL; + EINA_LIST_FOREACH(channel_list, l, channel_info) { + ly = util_add_layout(priv->list, GRP_CHANNELNUMBER_LIST_ITEM); + if (!ly) { + _ERR("failed to create layout"); + return; + } + + elm_object_focus_allow_set(ly, EINA_TRUE); + + snprintf(buf, sizeof(buf), "%ld %s", + channel_info->channel_major, + channel_info->channel_name); + elm_object_text_set(ly, buf); + + inputmgr_add_callback(ly, 0, &channel_handler, + (void *) channel_info->service_id); + + elm_box_pack_end(priv->list, ly); + + if (!first) { + first = ly; + elm_object_focus_set(ly, EINA_TRUE); + } + } + + if (first && ly) + elm_object_focus_next_object_set(first, ly, ELM_FOCUS_UP); + + if (channel_list) + tv_channel_del_list(channel_list); +} + +static void _update_number_info(struct _priv *priv) +{ + char buf[BUF_MAX]; + + if (priv->major < 0) { + _ERR("Wrong channel number"); + return; + } + + snprintf(buf, sizeof(buf), "%d", priv->major); + + elm_object_part_text_set(priv->base, PART_CHANNELNUMBER_NUMBER, buf); + + _update_channel_list(priv); +} + +static int _get_number(const char *keyname) +{ + static const char const *keys[] = { + KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, + KEY_5, KEY_6, KEY_7, KEY_8, KEY_9 + }; + + int i; + + if (!keyname) { + _ERR("failed to get keyname"); + return -1; + } + + for (i = 0; i < sizeof(keys) / sizeof(*keys); i++) { + if (!strcmp(keyname, keys[i])) + return i; + } + + return -1; +} + +static void _number_reset(struct _priv *priv) +{ + priv->major = -1; + priv->minor = -1; + + _release_channel_handler(priv->list); + elm_box_clear(priv->list); +} + +static void _number_tuning(struct _priv *priv, const char *keyname) +{ + int num; + + if (!priv || !keyname) { + _ERR("failed to get priv and keyname"); + return; + } + + num = _get_number(keyname); + if (num < 0 || (num == 0 && priv->major <= 0)) + goto error; + + if (priv->major < 0) { + priv->major = num; + } else { + priv->major *= 10; + priv->major += num; + } + + if (priv->major > MAJOR_MAX) + goto error; + + _update_number_info(priv); + + return; + +error: + _number_reset(priv); +} + +static Evas_Object *_create(Evas_Object *win, void *data) +{ + struct _priv *priv; + Evas_Object *scroll = NULL; + + if (!win) { + _ERR("failed to get win object"); + return NULL; + } + + priv = calloc(1, sizeof(*priv)); + if (!priv) { + _ERR("failed to allocate priv"); + return NULL; + } + + priv->base = elm_layout_add(win); + if (!priv->base) { + _ERR("failed to create base object"); + goto error; + } + elm_layout_file_set(priv->base, EDJEFILE, GRP_VIEW_CHANNELNUMBER); + + evas_object_size_hint_weight_set(priv->base, + EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_win_resize_object_add(win, priv->base); + + scroll = util_add_scroller(priv->base, PART_CHANNELNUMBER_LIST); + if (!scroll) { + _ERR("failed to create scroll"); + goto error; + } + + elm_object_focus_allow_set(scroll, EINA_FALSE); + + priv->list = util_add_box(scroll, false); + if (!priv->list) { + _ERR("failed to create box"); + goto error; + } + + elm_box_align_set(priv->list, 0.5, 0.0); + + elm_object_focus_allow_set(priv->list, EINA_TRUE); + elm_object_focus_set(priv->list, EINA_TRUE); + + viewmgr_set_view_data(VIEW_CHANNELNUMBER, priv); + + inputmgr_add_callback(priv->base, 0, &key_handler, priv); + + return priv->base; + +error: + _ERR("failed to create view"); + + if (priv->list) + evas_object_del(priv->list); + if (scroll) + evas_object_del(scroll); + if (priv->base) + evas_object_del(priv->base); + + free(priv); + + return NULL; +} + +static void _show(void *view_data) +{ + struct _priv *priv; + + if (!view_data) { + _ERR("failed to get view data"); + return; + } + + priv = view_data; + + _start_hide_timer(priv); + + evas_object_show(priv->base); + + viewmgr_hide_view(VIEW_CHANNELINFO); +} + +static void _hide(void *view_data) +{ + struct _priv *priv; + + if (!view_data) { + _ERR("failed to get view data"); + return; + } + + priv = view_data; + + _stop_hide_timer(priv); + _number_reset(priv); + + evas_object_hide(priv->base); +} + +static void _destroy(void *view_data) +{ + struct _priv *priv; + + if (!view_data) { + _ERR("failed to get view data"); + return; + } + + priv = view_data; + + inputmgr_remove_callback(priv->base, &key_handler); + + evas_object_del(priv->base); + + free(priv); +} + +static void _update(void *view_data, int type, void *data) +{ + struct _priv *priv; + + if (!view_data) { + _ERR("failed to get view data"); + return; + } + + priv = view_data; + + if (type == UPDATE_TYPE_TIMER) { + _start_hide_timer(priv); + } else if (type == UPDATE_TYPE_INPUT_KEY_DOWN) { + Evas_Event_Key_Down *ev = data; + + if (!ev) { + _ERR("failed to get ev"); + return; + } + + if (_get_number(ev->keyname) != -1) + _number_tuning(priv, ev->keyname); + + _start_hide_timer(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_BACK) || + !strcmp(ev->keyname, KEY_BACK_REMOTE)) { + viewmgr_hide_view(VIEW_CHANNELNUMBER); + } + } +} + +static view_class vclass = { + .view_id = VIEW_CHANNELNUMBER, + .create = _create, + .show = _show, + .hide = _hide, + .destroy = _destroy, + .update = _update +}; + +view_class *view_channelnumber_get_vclass(void) +{ + return &vclass; +} -- 2.7.4 From 3df30c5812af648c8cf4c33f6009a925d8a60df6 Mon Sep 17 00:00:00 2001 From: "jinwoo.shin" Date: Thu, 16 Jul 2015 13:44:53 +0900 Subject: [PATCH 08/16] Add error view for no channel and no signal Change-Id: I99d426fb19b72817e14b16e3d1f98491136b764b Signed-off-by: jinwoo.shin --- CMakeLists.txt | 1 + data/live-tv.edc | 1 + data/view/error.edc | 86 ++++++++++++++++++++++++ include/define.h | 5 ++ include/strings.h | 4 ++ include/view.h | 5 ++ src/layout_channelinfo_search.c | 3 +- src/main.c | 2 + src/view_channelnumber.c | 3 +- src/view_error.c | 140 ++++++++++++++++++++++++++++++++++++++++ 10 files changed, 246 insertions(+), 4 deletions(-) create mode 100644 data/view/error.edc create mode 100644 src/view_error.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 9b42838..34340b1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,6 +44,7 @@ SET(SRCS src/main.c src/layout_channelinfo_list.c src/layout_channelinfo_search.c src/view_channelnumber.c + src/view_error.c src/util.c src/tv_service.c) diff --git a/data/live-tv.edc b/data/live-tv.edc index 8a77133..2c43574 100644 --- a/data/live-tv.edc +++ b/data/live-tv.edc @@ -19,4 +19,5 @@ collections { #include "view/channelinfo.edc" #include "view/channelnumber.edc" + #include "view/error.edc" } diff --git a/data/view/error.edc b/data/view/error.edc new file mode 100644 index 0000000..2d1b3e9 --- /dev/null +++ b/data/view/error.edc @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http,//www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "../../include/define.h" + +group { + name, GRP_VIEW_ERROR; + parts { + part { + name, "bg"; + type, RECT; + scale, 1; + description { + state, "default" 0.0; + color, 244 244 244 255; + } + } + part { + name, "part.error"; + type, RECT; + scale, 1; + description { + state, "default" 0.0; + rel1.relative, 0.5 0.5; + rel2.relative, 0.5 0.5; + min, 0 82; + align, 0.5 0.5; + fixed, 0 1; + } + + part { + name, PART_ERROR_TITLE; + type, TEXT; + scale, 1; + description { + rel1.relative, 0.0 0.0; + rel2.relative, 1.0 0.0; + text { + font, FONT_LIGHT; + size, 28; + align, 0.5 0.5; + min, 1 0; + ellipsis, -1; + } + color, 103 103 103 255; + min, 0 36; + align, 0.5 0.0; + fixed, 1 1; + } + } + part { + name, PART_ERROR_TEXT; + type, TEXT; + scale, 1; + description { + rel1.relative, 0.0 1.0; + rel2.relative, 1.0 1.0; + text { + font, FONT_LIGHT; + size, 28; + align, 0.5 0.5; + min, 1 0; + ellipsis, -1; + } + color, 116 116 116 255; + min, 0 36; + align, 0.5 1.0; + fixed, 1 1; + } + } + } + } +} diff --git a/include/define.h b/include/define.h index 79000c3..372275a 100644 --- a/include/define.h +++ b/include/define.h @@ -73,4 +73,9 @@ #define PART_CHANNELNUMBER_LIST "part.channelnumber.list" #define GRP_CHANNELNUMBER_LIST_ITEM "grp.channelnumber.list.item" +#define VIEW_ERROR "VIEW_ERROR" +#define GRP_VIEW_ERROR "grp.view.error" +#define PART_ERROR_TITLE "part.error.title" +#define PART_ERROR_TEXT "part.error.text" + #endif /* __LIVETV_DEFINE_H__*/ diff --git a/include/strings.h b/include/strings.h index cb65a19..486c0bd 100644 --- a/include/strings.h +++ b/include/strings.h @@ -20,5 +20,9 @@ #define STR_NOTITLE "No Information" #define STR_NOTIME "No Data" #define STR_CHANNEL_PREFIX "CH." +#define STR_NOCHANNEL_TITLE "No Channel" +#define STR_NOCHANNEL_TEXT "The channel is not found" +#define STR_NOSIGNAL_TITLE "Weak or No Signal" +#define STR_NOSIGNAL_TEXT "Check the antenna cable connection" #endif /* __AIR_LIVETV_STRINGS_H__*/ diff --git a/include/view.h b/include/view.h index 936f0fe..8e0fc8e 100644 --- a/include/view.h +++ b/include/view.h @@ -17,15 +17,20 @@ #ifndef __LIVETV_VIEW_H__ #define __LIVETV_VIEW_H__ +#include "tv.h" + enum _update_type { UPDATE_TYPE_TIMER, UPDATE_TYPE_INPUT_KEY_DOWN, UPDATE_TYPE_INPUT_KEY_UP, + UPDATE_TYPE_NOCHANNEL, + UPDATE_TYPE_NOSIGNAL, }; void draw_channel_info(Evas_Object *obj, const struct tv_channel_info *channel_info); view_class *view_channelnumber_get_vclass(void); view_class *view_channelinfo_get_vclass(void); +view_class *view_error_get_vclass(void); #endif /* __LIVETV_VIEW_H__*/ diff --git a/src/layout_channelinfo_search.c b/src/layout_channelinfo_search.c index ef62aca..bdaabae 100644 --- a/src/layout_channelinfo_search.c +++ b/src/layout_channelinfo_search.c @@ -92,9 +92,8 @@ static void _release_channel_handler(Evas_Object *obj) child = elm_box_children_get(obj); - EINA_LIST_FOREACH(child, l, ly) { + EINA_LIST_FOREACH(child, l, ly) inputmgr_remove_callback(ly, &channel_handler); - } if (child) eina_list_free(child); diff --git a/src/main.c b/src/main.c index 9cdc317..c806937 100644 --- a/src/main.c +++ b/src/main.c @@ -229,6 +229,7 @@ static bool _create(void *data) viewmgr_add_view(view_channelinfo_get_vclass(), NULL); viewmgr_add_view(view_channelnumber_get_vclass(), NULL); + viewmgr_add_view(view_error_get_vclass(), NULL); r = tv_create(); if (r < 0) { @@ -269,6 +270,7 @@ static void _terminate(void *data) viewmgr_remove_view(VIEW_CHANNELINFO); viewmgr_remove_view(VIEW_CHANNELNUMBER); + viewmgr_remove_view(VIEW_ERROR); viewmgr_destroy(); evas_object_del(ad->win); diff --git a/src/view_channelnumber.c b/src/view_channelnumber.c index f478b31..ada44ad 100644 --- a/src/view_channelnumber.c +++ b/src/view_channelnumber.c @@ -152,9 +152,8 @@ static void _release_channel_handler(Evas_Object *obj) child = elm_box_children_get(obj); - EINA_LIST_FOREACH(child, l, ly) { + EINA_LIST_FOREACH(child, l, ly) inputmgr_remove_callback(ly, &channel_handler); - } if (child) eina_list_free(child); diff --git a/src/view_error.c b/src/view_error.c new file mode 100644 index 0000000..2983c25 --- /dev/null +++ b/src/view_error.c @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include "define.h" +#include "view.h" + +struct _priv { + Evas_Object *base; +}; + +static Evas_Object *_create(Evas_Object *win, void *data) +{ + struct _priv *priv; + + if (!win) { + _ERR("failed to get win object"); + return NULL; + } + + priv = calloc(1, sizeof(*priv)); + if (!priv) { + _ERR("failed to allocate priv"); + return NULL; + } + + priv->base = elm_layout_add(win); + if (!priv->base) { + _ERR("failed to create base object"); + free(priv); + return NULL; + } + elm_layout_file_set(priv->base, EDJEFILE, GRP_VIEW_ERROR); + + evas_object_size_hint_weight_set(priv->base, + EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_win_resize_object_add(win, priv->base); + + viewmgr_set_view_data(VIEW_ERROR, priv); + + return priv->base; +} + +static void _show(void *view_data) +{ + struct _priv *priv; + + if (!view_data) { + _ERR("failed to get view data"); + return; + } + + priv = view_data; + + evas_object_show(priv->base); +} + +static void _hide(void *view_data) +{ + struct _priv *priv; + + if (!view_data) { + _ERR("failed to get view data"); + return; + } + + priv = view_data; + + evas_object_hide(priv->base); +} + +static void _destroy(void *view_data) +{ + struct _priv *priv; + + if (!view_data) { + _ERR("failed to get view data"); + return; + } + + priv = view_data; + + evas_object_del(priv->base); + + free(priv); +} + +static void _update(void *view_data, int type, void *data) +{ + struct _priv *priv; + + if (!view_data) { + _ERR("failed to get view data"); + return; + } + + priv = view_data; + + if (type == UPDATE_TYPE_NOCHANNEL) { + elm_object_part_text_set(priv->base, + PART_ERROR_TITLE, STR_NOCHANNEL_TITLE); + elm_object_part_text_set(priv->base, + PART_ERROR_TEXT, STR_NOCHANNEL_TEXT); + } else if (type == UPDATE_TYPE_NOSIGNAL) { + elm_object_part_text_set(priv->base, + PART_ERROR_TITLE, STR_NOSIGNAL_TITLE); + elm_object_part_text_set(priv->base, + PART_ERROR_TEXT, STR_NOSIGNAL_TEXT); + } +} + +static view_class vclass = { + .view_id = VIEW_ERROR, + .create = _create, + .show = _show, + .hide = _hide, + .destroy = _destroy, + .update = _update, +}; + +view_class *view_error_get_vclass(void) +{ + return &vclass; +} -- 2.7.4 From 316a7bbd83927bd357f765e0b83a9f87e79ae4e3 Mon Sep 17 00:00:00 2001 From: "jinwoo.shin" Date: Fri, 17 Jul 2015 18:35:10 +0900 Subject: [PATCH 09/16] Change of global key event and focus handling Change-Id: If902c7bf2462132e2c5fad4f36521d0029f8a87d Signed-off-by: jinwoo.shin --- src/layout_channelinfo.c | 2 - src/layout_channelinfo_search.c | 1 + src/main.c | 49 +++++++++++++++------- src/view_channelinfo.c | 91 +++++++++++++++++++++++++---------------- src/view_channelnumber.c | 20 +++------ 5 files changed, 95 insertions(+), 68 deletions(-) diff --git a/src/layout_channelinfo.c b/src/layout_channelinfo.c index 5cdb323..d74ce81 100644 --- a/src/layout_channelinfo.c +++ b/src/layout_channelinfo.c @@ -117,8 +117,6 @@ static void _show(void *layout_data) elm_object_content_set(priv->base, priv->layout); evas_object_show(priv->layout); - - elm_object_focus_allow_set(priv->base, EINA_TRUE); } static void _hide(void *layout_data) diff --git a/src/layout_channelinfo_search.c b/src/layout_channelinfo_search.c index bdaabae..0382a6f 100644 --- a/src/layout_channelinfo_search.c +++ b/src/layout_channelinfo_search.c @@ -61,6 +61,7 @@ static void _tune_channel(void *data) _ERR("failed to tune with service id"); viewmgr_hide_view(VIEW_CHANNELINFO); + viewmgr_show_view(VIEW_CHANNELINFO); } static void _key_down_cb(int id, void *data, Evas *e, Evas_Object *obj, diff --git a/src/main.c b/src/main.c index c806937..bfcfa18 100644 --- a/src/main.c +++ b/src/main.c @@ -32,6 +32,8 @@ SET_TAG(PACKAGE) struct _appdata { const char *name; Evas_Object *win; + Ecore_Event_Handler *key_down; + Ecore_Event_Handler *key_up; int is_signal; }; @@ -60,48 +62,58 @@ static struct key_map g_kmap[] = { }, }; -static void _key_down_cb(int id, void *data, Evas *e, Evas_Object *obj, - Evas_Event_Key_Down *ev) +static Eina_Bool _key_down_cb(void *data, int type, void *ei) { + Evas_Event_Key_Down *ev = ei; size_t i, j; + if (!strcmp(ev->keyname, KEY_ENTER) || + !strcmp(ev->keyname, KEY_ENTER_REMOTE)) { + if (viewmgr_active_view_count() > 0) + return ECORE_CALLBACK_PASS_ON; + } + 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_DOWN, ev); - return; + viewmgr_show_view(g_kmap[i].view); + return ECORE_CALLBACK_DONE; } j++; } } + + return ECORE_CALLBACK_PASS_ON; } -static void _key_up_cb(int id, void *data, Evas *e, Evas_Object *obj, - Evas_Event_Key_Up *ev) +static Eina_Bool _key_up_cb(void *data, int type, void *ei) { + Evas_Event_Key_Up *ev = ei; size_t i, j; + if (!strcmp(ev->keyname, KEY_ENTER) || + !strcmp(ev->keyname, KEY_ENTER_REMOTE)) { + if (viewmgr_active_view_count() > 0) + return ECORE_CALLBACK_PASS_ON; + } + 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; + return ECORE_CALLBACK_DONE; } j++; } } -} -static input_handler key_handler = { - .key_down = _key_down_cb, - .key_up = _key_up_cb, -}; + return ECORE_CALLBACK_PASS_ON; +} static Evas_Object *_add_win(const char *name) { @@ -248,7 +260,11 @@ static bool _create(void *data) ad->win = win; tv_signal_cb_set(_tv_signal_cb, ad); - inputmgr_add_callback(ad->win, 0, &key_handler, NULL); + ad->key_down = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, + _key_down_cb, NULL); + ad->key_up = ecore_event_handler_add(ECORE_EVENT_KEY_UP, + _key_up_cb, NULL); + return true; } @@ -266,7 +282,10 @@ static void _terminate(void *data) if (ad->win) { tv_destroy(); - inputmgr_remove_callback(ad->win, &key_handler); + if (ad->key_down) + ecore_event_handler_del(ad->key_down); + if (ad->key_up) + ecore_event_handler_del(ad->key_up); viewmgr_remove_view(VIEW_CHANNELINFO); viewmgr_remove_view(VIEW_CHANNELNUMBER); diff --git a/src/view_channelinfo.c b/src/view_channelinfo.c index 86618e7..c607039 100644 --- a/src/view_channelinfo.c +++ b/src/view_channelinfo.c @@ -44,18 +44,51 @@ struct _priv { layoutmgr *lmgr; }; -static void _update(void *view_data, int type, void *data); +static void _hide_current_layout(struct _priv *priv) +{ + if (!priv->current_layout) + return; -static void _key_down_cb(int id, void *data, Evas *e, Evas_Object *obj, - Evas_Event_Key_Down *ev) + layoutmgr_hide_layout(priv->lmgr, priv->current_layout); + priv->current_layout = NULL; +} + +static void _set_current_layout(struct _priv *priv, const char *layout_id) { - _update(data, UPDATE_TYPE_INPUT_KEY_DOWN, ev); + if (priv->current_layout && layout_id && + !strcmp(priv->current_layout, layout_id)) + return; + + if (priv->current_layout) + layoutmgr_hide_layout(priv->lmgr, priv->current_layout); + + layoutmgr_show_layout(priv->lmgr, layout_id); + priv->current_layout = layout_id; } -static void _key_up_cb(int id, void *data, Evas *e, Evas_Object *obj, - Evas_Event_Key_Up *ev) +static void _key_down_cb(int id, void *data, Evas *e, Evas_Object *obj, + Evas_Event_Key_Down *ev) { - _update(data, UPDATE_TYPE_INPUT_KEY_UP, ev); + struct _priv *priv; + + if (!data) { + _ERR("failed to get data"); + return; + } + + priv = data; + + if (!strcmp(ev->keyname, KEY_ENTER) || + !strcmp(ev->keyname, KEY_ENTER_REMOTE)) { + _set_current_layout(priv, LAYOUT_CHANNELINFO_SEARCH); + } else if (!strcmp(ev->keyname, KEY_BACK) || + !strcmp(ev->keyname, KEY_BACK_REMOTE) || + !strcmp(ev->keyname, KEY_EXIT)) { + viewmgr_hide_view(VIEW_CHANNELINFO); + } else { + viewmgr_update_view(VIEW_CHANNELINFO, + UPDATE_TYPE_TIMER, START_HIDE_TIMER); + } } static void _mouse_move_cb(int id, void *data, Evas *e, Evas_Object *obj, @@ -67,7 +100,6 @@ static void _mouse_move_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, .mouse_move = _mouse_move_cb, }; @@ -275,28 +307,6 @@ void draw_channel_info(Evas_Object *obj, UPDATE_TYPE_TIMER, START_HIDE_TIMER); } -static void _hide_current_layout(struct _priv *priv) -{ - if (!priv->current_layout) - return; - - layoutmgr_hide_layout(priv->lmgr, priv->current_layout); - priv->current_layout = NULL; -} - -static void _set_current_layout(struct _priv *priv, const char *layout_id) -{ - if (priv->current_layout && layout_id && - !strcmp(priv->current_layout, layout_id)) - return; - - if (priv->current_layout) - layoutmgr_hide_layout(priv->lmgr, priv->current_layout); - - layoutmgr_show_layout(priv->lmgr, layout_id); - priv->current_layout = layout_id; -} - static Evas_Object *_create(Evas_Object *win, void *data) { struct _priv *priv; @@ -319,6 +329,7 @@ static Evas_Object *_create(Evas_Object *win, void *data) return NULL; } elm_layout_file_set(priv->base, EDJEFILE, GRP_VIEW_CHANNELINFO); + elm_object_focus_allow_set(priv->base, EINA_TRUE); evas_object_size_hint_weight_set(priv->base, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); @@ -350,6 +361,10 @@ static void _show(void *view_data) priv = view_data; evas_object_show(priv->base); + elm_object_focus_set(priv->base, EINA_TRUE); + + if (!priv->current_layout) + _set_current_layout(priv, LAYOUT_CHANNELINFO); } static void _hide(void *view_data) @@ -430,11 +445,14 @@ static void _update(void *view_data, int type, void *data) !strcmp(ev->keyname, KEY_CHANNELUP_REMOTE) || !strcmp(ev->keyname, KEY_CHANNELDOWN) || !strcmp(ev->keyname, KEY_CHANNELDOWN_REMOTE)) { + if (priv->current_layout && + !strcmp(priv->current_layout, + LAYOUT_CHANNELINFO_SEARCH)) + return; + _set_current_layout(priv, LAYOUT_CHANNELINFO_LIST); layoutmgr_update_layout(priv->lmgr, LAYOUT_CHANNELINFO_LIST, type, ev); - } else { - _start_hide_timer(priv); } } else if (type == UPDATE_TYPE_INPUT_KEY_UP) { Evas_Event_Key_Up *ev = data; @@ -448,13 +466,14 @@ static void _update(void *view_data, int type, void *data) !strcmp(ev->keyname, KEY_CHANNELUP_REMOTE) || !strcmp(ev->keyname, KEY_CHANNELDOWN) || !strcmp(ev->keyname, KEY_CHANNELDOWN_REMOTE)) { + if (priv->current_layout && + !strcmp(priv->current_layout, + LAYOUT_CHANNELINFO_SEARCH)) + return; + _set_current_layout(priv, LAYOUT_CHANNELINFO_LIST); layoutmgr_update_layout(priv->lmgr, LAYOUT_CHANNELINFO_LIST, type, ev); - } else if (!strcmp(ev->keyname, KEY_BACK) || - !strcmp(ev->keyname, KEY_BACK_REMOTE) || - !strcmp(ev->keyname, KEY_EXIT)) { - viewmgr_hide_view(VIEW_CHANNELINFO); } } } diff --git a/src/view_channelnumber.c b/src/view_channelnumber.c index ada44ad..f016f86 100644 --- a/src/view_channelnumber.c +++ b/src/view_channelnumber.c @@ -26,6 +26,7 @@ #define HIDE_DUR 3.0 #define BUF_MAX 128 +#define NUMBER_MAX 3 struct _priv { Evas_Object *base; @@ -36,18 +37,13 @@ struct _priv { int minor; }; -static void _update(void *view_data, int type, void *data); - static void _key_down_cb(int id, void *data, Evas *e, Evas_Object *obj, Evas_Event_Key_Down *ev) { - _update(data, UPDATE_TYPE_INPUT_KEY_DOWN, ev); -} - -static void _key_up_cb(int id, void *data, Evas *e, Evas_Object *obj, - Evas_Event_Key_Up *ev) -{ - _update(data, UPDATE_TYPE_INPUT_KEY_UP, ev); + if (!strcmp(ev->keyname, KEY_BACK) || + !strcmp(ev->keyname, KEY_BACK_REMOTE)) { + viewmgr_hide_view(VIEW_CHANNELNUMBER); + } } static void _mouse_move_cb(int id, void *data, Evas *e, Evas_Object *obj, @@ -59,7 +55,6 @@ static void _mouse_move_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, .mouse_move = _mouse_move_cb, }; @@ -435,11 +430,6 @@ static void _update(void *view_data, int type, void *data) _ERR("failed to get ev"); return; } - - if (!strcmp(ev->keyname, KEY_BACK) || - !strcmp(ev->keyname, KEY_BACK_REMOTE)) { - viewmgr_hide_view(VIEW_CHANNELNUMBER); - } } } -- 2.7.4 From 01f1b370cbdbd46765ab9c000ed4253f4915b8bf Mon Sep 17 00:00:00 2001 From: "jinwoo.shin" Date: Mon, 20 Jul 2015 14:58:14 +0900 Subject: [PATCH 10/16] Update channel number UX Change-Id: I6467cdf570398f218add973d5334b9a899339d11 Signed-off-by: jinwoo.shin --- data/view/channelnumber.edc | 146 +++++++++++++++++++++++++++++++------------- include/define.h | 2 + src/main.c | 3 +- src/tv_service.c | 2 +- src/util.c | 2 + src/view_channelinfo.c | 2 + src/view_channelnumber.c | 101 +++++++++++++----------------- 7 files changed, 157 insertions(+), 101 deletions(-) diff --git a/data/view/channelnumber.edc b/data/view/channelnumber.edc index 9892029..387b8f7 100644 --- a/data/view/channelnumber.edc +++ b/data/view/channelnumber.edc @@ -159,8 +159,8 @@ group { } } part { - name, "bg.list.border"; - type, RECT; + name, PART_CHANNELNUMBER_LIST; + type, SWALLOW; scale, 1; description { state, "default" 0.0; @@ -172,48 +172,8 @@ group { to, "padding.list"; relative, 1.0 1.0; } - color, COLOR_OPTION_BORDER; min, 216 224; align, 0.0 0.0; - fixed, 1 1; - } - } - part { - name, "bg.list"; - type, RECT; - scale, 1; - description { - state, "default" 0.0; - rel1 { - to, "bg.list.border"; - relative, 0.5 0.5; - } - rel2 { - to, "bg.list.border"; - relative, 0.5 0.5; - } - color, COLOR_BG_NORMAL; - min, 214 222; - align, 0.5 0.5; - fixed, 1 1; - } - } - part { - name, PART_CHANNELNUMBER_LIST; - type, SWALLOW; - scale, 1; - description { - state, "default" 0.0; - rel1 { - to, "bg.list"; - relative, 0.0 0.0; - } - rel2 { - to, "bg.list"; - relative, 1.0 1.0; - } - align, 0.0 0.0; - fixed, 1 1; } } } @@ -304,6 +264,94 @@ group { color, COLOR_TEXT_FOCUSED; } } + part { + name, "border.top"; + type, RECT; + scale, 1; + description { + state, "default" 0.0; + rel1 { + to, "bg"; + relative, 0.0 0.0; + } + rel2 { + to, "bg"; + relative, 1.0 0.0; + } + color, COLOR_OPTION_BORDER; + min, 0 1; + align, 0.0 0.0; + visible, 0; + } + description { + state, "first" 0.0; + inherit, "default" 0.0; + visible, 1; + } + } + part { + name, "border.left"; + type, RECT; + scale, 1; + description { + state, "default" 0.0; + rel1 { + to, "bg"; + relative, 0.0 0.0; + } + rel2 { + to, "bg"; + relative, 0.0 1.0; + } + color, COLOR_OPTION_BORDER; + min, 1 0; + align, 0.0 0.0; + } + } + part { + name, "border.bottom"; + type, RECT; + scale, 1; + description { + state, "default" 0.0; + rel1 { + to, "bg"; + relative, 0.0 1.0; + } + rel2 { + to, "bg"; + relative, 1.0 1.0; + } + color, COLOR_OPTION_BORDER; + min, 0 1; + align, 0.0 1.0; + visible, 0; + } + description { + state, "last" 0.0; + inherit, "default" 0.0; + visible, 1; + } + } + part { + name, "border.right"; + type, RECT; + scale, 1; + description { + state, "default" 0.0; + rel1 { + to, "bg"; + relative, 1.0 0.0; + } + rel2 { + to, "bg"; + relative, 1.0 1.0; + } + color, COLOR_OPTION_BORDER; + min, 1 0; + align, 1.0 0.0; + } + } } programs { program { @@ -322,6 +370,20 @@ group { target, "bg"; target, PART_TEXT; } + program { + name, "first"; + signal, SIGNAL_FIRST; + source, ""; + action, STATE_SET "first" 0.0; + target, "border.top"; + } + program { + name, "last"; + signal, SIGNAL_LAST; + source, ""; + action, STATE_SET "last" 0.0; + target, "border.bottom"; + } } } diff --git a/include/define.h b/include/define.h index 372275a..aedb0e9 100644 --- a/include/define.h +++ b/include/define.h @@ -29,6 +29,8 @@ #define SIGNAL_FOCUSED "elm,action,focus" #define SIGNAL_UNFOCUSED "elm,action,unfocus" +#define SIGNAL_FIRST "elm,state,first" +#define SIGNAL_LAST "elm,state,last" #define FONT_REGULAR "TizenSans" #define FONT_LIGHT "TizenSans:style=Light" diff --git a/src/main.c b/src/main.c index bfcfa18..6a846b1 100644 --- a/src/main.c +++ b/src/main.c @@ -79,7 +79,6 @@ static Eina_Bool _key_down_cb(void *data, int type, void *ei) if (!strcmp(ev->keyname, g_kmap[i].key[j])) { viewmgr_update_view(g_kmap[i].view, UPDATE_TYPE_INPUT_KEY_DOWN, ev); - viewmgr_show_view(g_kmap[i].view); return ECORE_CALLBACK_DONE; } j++; @@ -265,6 +264,8 @@ static bool _create(void *data) ad->key_up = ecore_event_handler_add(ECORE_EVENT_KEY_UP, _key_up_cb, NULL); + elm_config_focus_move_policy_set(ELM_FOCUS_MOVE_POLICY_IN); + return true; } diff --git a/src/tv_service.c b/src/tv_service.c index ea18fe7..ee44fac 100644 --- a/src/tv_service.c +++ b/src/tv_service.c @@ -120,7 +120,7 @@ static void init_data() channel = (TvServiceChannel *)g_malloc0(sizeof(TvServiceChannel)); init_constant_channel_data(channel); channel->service_id = i; - channel->major = (5 + i); + channel->major = (10 + i); channel->favorite = i % 2 == 0 ? TRUE : FALSE; snprintf(channel->program_name, PROGRAM_NAME_MAX_LEN - 1, "Super Channel %d", i); channel_list = g_list_append(channel_list, (gpointer)channel); diff --git a/src/util.c b/src/util.c index 43c098e..ba2acdd 100644 --- a/src/util.c +++ b/src/util.c @@ -86,6 +86,8 @@ Evas_Object *util_add_scroller(Evas_Object *parent, const char *part) evas_object_size_hint_weight_set(scroll, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_scroller_policy_set(scroll, ELM_SCROLLER_POLICY_OFF, + ELM_SCROLLER_POLICY_OFF); if (part) elm_object_part_content_set(parent, part, scroll); diff --git a/src/view_channelinfo.c b/src/view_channelinfo.c index c607039..a9fb0cd 100644 --- a/src/view_channelinfo.c +++ b/src/view_channelinfo.c @@ -454,6 +454,8 @@ static void _update(void *view_data, int type, void *data) layoutmgr_update_layout(priv->lmgr, LAYOUT_CHANNELINFO_LIST, type, ev); } + + viewmgr_show_view(VIEW_CHANNELINFO); } else if (type == UPDATE_TYPE_INPUT_KEY_UP) { Evas_Event_Key_Up *ev = data; diff --git a/src/view_channelnumber.c b/src/view_channelnumber.c index f016f86..89048ca 100644 --- a/src/view_channelnumber.c +++ b/src/view_channelnumber.c @@ -35,6 +35,7 @@ struct _priv { int major; int minor; + char number[NUMBER_MAX+1]; }; static void _key_down_cb(int id, void *data, Evas *e, Evas_Object *obj, @@ -46,19 +47,19 @@ static void _key_down_cb(int id, void *data, Evas *e, Evas_Object *obj, } } -static void _mouse_move_cb(int id, void *data, Evas *e, Evas_Object *obj, - Evas_Event_Mouse_Move *ev) -{ - viewmgr_update_view(VIEW_CHANNELNUMBER, - UPDATE_TYPE_TIMER, 0); -} - static input_handler key_handler = { .key_down = _key_down_cb, - .mouse_move = _mouse_move_cb, }; -static Eina_Bool _hide_timer(void *data) +static void _stop_hide_timer(struct _priv *priv) +{ + if (priv->hide_timer) { + ecore_timer_del(priv->hide_timer); + priv->hide_timer = NULL; + } +} + +static Eina_Bool _done_input(void *data) { struct _priv *priv; int r; @@ -68,13 +69,12 @@ static Eina_Bool _hide_timer(void *data) priv = data; - priv->hide_timer = NULL; - r = tv_channel_direct_tune(priv->major, priv->minor); if (r < 0) _ERR("invalid channel"); viewmgr_hide_view(VIEW_CHANNELNUMBER); + viewmgr_show_view(VIEW_CHANNELINFO); return ECORE_CALLBACK_CANCEL; } @@ -84,15 +84,7 @@ static void _start_hide_timer(struct _priv *priv) if (priv->hide_timer) ecore_timer_reset(priv->hide_timer); else - priv->hide_timer = ecore_timer_add(HIDE_DUR, _hide_timer, priv); -} - -static void _stop_hide_timer(struct _priv *priv) -{ - if (priv->hide_timer) { - ecore_timer_del(priv->hide_timer); - priv->hide_timer = NULL; - } + priv->hide_timer = ecore_timer_add(HIDE_DUR, _done_input, priv); } static void _tune_channel(void *data) @@ -132,9 +124,17 @@ static void _channel_mouse_down_cb(int id, void *data, Evas *e, _tune_channel(data); } +static void _channel_focused_cb(int id, void *data, + Evas_Object *obj, Elm_Object_Item *it) +{ + viewmgr_update_view(VIEW_CHANNELNUMBER, + UPDATE_TYPE_TIMER, 0); +} + static input_handler channel_handler = { .key_down = _channel_key_down_cb, .mouse_down = _channel_mouse_down_cb, + .focused = _channel_focused_cb, }; static void _release_channel_handler(Evas_Object *obj) @@ -166,6 +166,13 @@ static void _update_channel_list(struct _priv *priv) _release_channel_handler(priv->list); elm_box_clear(priv->list); + if (!channel_list) { + evas_object_hide(priv->list); + return; + } + + evas_object_show(priv->list); + first = NULL; ly = NULL; EINA_LIST_FOREACH(channel_list, l, channel_info) { @@ -190,11 +197,15 @@ static void _update_channel_list(struct _priv *priv) if (!first) { first = ly; elm_object_focus_set(ly, EINA_TRUE); + elm_object_signal_emit(ly, SIGNAL_FIRST, ""); } } - if (first && ly) + if (first && ly) { elm_object_focus_next_object_set(first, ly, ELM_FOCUS_UP); + elm_object_focus_next_object_set(ly, first, ELM_FOCUS_DOWN); + elm_object_signal_emit(ly, SIGNAL_LAST, ""); + } if (channel_list) tv_channel_del_list(channel_list); @@ -202,16 +213,13 @@ static void _update_channel_list(struct _priv *priv) static void _update_number_info(struct _priv *priv) { - char buf[BUF_MAX]; - - if (priv->major < 0) { + if (!priv->number) { _ERR("Wrong channel number"); return; } - snprintf(buf, sizeof(buf), "%d", priv->major); - - elm_object_part_text_set(priv->base, PART_CHANNELNUMBER_NUMBER, buf); + elm_object_part_text_set(priv->base, + PART_CHANNELNUMBER_NUMBER, priv->number); _update_channel_list(priv); } @@ -240,8 +248,8 @@ static int _get_number(const char *keyname) static void _number_reset(struct _priv *priv) { + memset(priv->number, '\0', sizeof(char) * NUMBER_MAX + 1); priv->major = -1; - priv->minor = -1; _release_channel_handler(priv->list); elm_box_clear(priv->list); @@ -249,33 +257,18 @@ static void _number_reset(struct _priv *priv) static void _number_tuning(struct _priv *priv, const char *keyname) { - int num; - - if (!priv || !keyname) { - _ERR("failed to get priv and keyname"); + if (!keyname) { + _ERR("failed to get keyname"); return; } - num = _get_number(keyname); - if (num < 0 || (num == 0 && priv->major <= 0)) - goto error; - - if (priv->major < 0) { - priv->major = num; - } else { - priv->major *= 10; - priv->major += num; - } - - if (priv->major > MAJOR_MAX) - goto error; + strncat(priv->number, keyname, 1); + priv->major = atoi(priv->number); _update_number_info(priv); - return; - -error: - _number_reset(priv); + if (strlen(priv->number) == NUMBER_MAX) + _done_input(priv); } static Evas_Object *_create(Evas_Object *win, void *data) @@ -311,19 +304,13 @@ static Evas_Object *_create(Evas_Object *win, void *data) goto error; } - elm_object_focus_allow_set(scroll, EINA_FALSE); - priv->list = util_add_box(scroll, false); if (!priv->list) { _ERR("failed to create box"); goto error; } - elm_box_align_set(priv->list, 0.5, 0.0); - elm_object_focus_allow_set(priv->list, EINA_TRUE); - elm_object_focus_set(priv->list, EINA_TRUE); - viewmgr_set_view_data(VIEW_CHANNELNUMBER, priv); inputmgr_add_callback(priv->base, 0, &key_handler, priv); @@ -419,10 +406,10 @@ static void _update(void *view_data, int type, void *data) return; } + viewmgr_show_view(VIEW_CHANNELNUMBER); + if (_get_number(ev->keyname) != -1) _number_tuning(priv, ev->keyname); - - _start_hide_timer(priv); } else if (type == UPDATE_TYPE_INPUT_KEY_UP) { Evas_Event_Key_Up *ev = data; -- 2.7.4 From a1547986f5ff3a92fe4323f0e818f66abefc1907 Mon Sep 17 00:00:00 2001 From: "jinwoo.shin" Date: Tue, 21 Jul 2015 13:22:26 +0900 Subject: [PATCH 11/16] Add channel history Change-Id: I06f86572c3df25fb6c48f844689f6494ea565e47 Signed-off-by: jinwoo.shin --- src/tv.c | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/src/tv.c b/src/tv.c index fff8b6d..b0da082 100644 --- a/src/tv.c +++ b/src/tv.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -612,6 +613,14 @@ void tv_channel_del_list(Eina_List *channel_list) free(data); } +void _tv_channel_add_history(int service_id) +{ + char buf[128]; + + snprintf(buf, sizeof(buf), "%d", service_id); + app_contents_recent_add(CONTENTS_CHANNEL, buf); +} + /** * Tunes to specific channel with service id. * @@ -633,6 +642,8 @@ int tv_channel_tune_with_service_id(int service_id) return -1; } + _tv_channel_add_history(service_id); + g_tv_info.viewing_locked_channel = -1; return 0; @@ -665,6 +676,8 @@ int tv_channel_tune(void) return -1; } + _tv_channel_add_history(service_id); + g_tv_info.viewing_locked_channel = -1; return 0; @@ -754,6 +767,8 @@ int tv_channel_tune_locked_channel(int service_id, char *password) return -1; } + _tv_channel_add_history(service_id); + g_tv_info.viewing_locked_channel = service_id; return 0; @@ -769,7 +784,7 @@ int tv_channel_tune_locked_channel(int service_id, char *password) int tv_channel_next(void) { TvServiceAntenna antenna_type; - int r; + int service_id, r; if (!g_tv_info.live_svc) { _ERR("failed to get live service"); @@ -791,6 +806,14 @@ int tv_channel_next(void) g_tv_info.viewing_locked_channel = -1; + r = tv_service_live_get_service_id(g_tv_info.live_svc, &service_id); + if (r < 0) { + _ERR("failed to get service id"); + return -1; + } + + _tv_channel_add_history(service_id); + return 0; } @@ -804,7 +827,7 @@ int tv_channel_next(void) int tv_channel_prev(void) { TvServiceAntenna antenna_type; - int r; + int service_id, r; if (!g_tv_info.live_svc) { _ERR("failed to get live service"); @@ -826,6 +849,14 @@ int tv_channel_prev(void) g_tv_info.viewing_locked_channel = -1; + r = tv_service_live_get_service_id(g_tv_info.live_svc, &service_id); + if (r < 0) { + _ERR("failed to get service id"); + return -1; + } + + _tv_channel_add_history(service_id); + return 0; } -- 2.7.4 From 0398000574135780958f3253e093ca0fca15bf77 Mon Sep 17 00:00:00 2001 From: "jinwoo.shin" Date: Tue, 21 Jul 2015 15:16:30 +0900 Subject: [PATCH 12/16] Add tv service integration Change-Id: I2f70eb50a47195ad4bd1ef8c98130757634e9b9e Signed-off-by: jinwoo.shin --- CMakeLists.txt | 7 ++++--- packaging/org.tizen.live-tv.spec | 2 ++ src/main.c | 40 ---------------------------------------- 3 files changed, 6 insertions(+), 43 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 34340b1..de9e819 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -45,8 +45,7 @@ SET(SRCS src/main.c src/layout_channelinfo_search.c src/view_channelnumber.c src/view_error.c - src/util.c - src/tv_service.c) + src/util.c) SET(TARGET_EDJ "${PROJECT_NAME}.edj") SET(THEME_EDJ "${PROJECT_NAME}-theme.edj") @@ -67,7 +66,9 @@ pkg_check_modules(PKGS REQUIRED capi-appfw-application app-utils vconf - gobject-2.0) + glib-2.0 + gobject-2.0 + tv-service) FOREACH(flag ${PKGS_CFLAGS}) SET(EXTRA_CFLGAS "${EXTRA_CFLGAS} ${flag}") diff --git a/packaging/org.tizen.live-tv.spec b/packaging/org.tizen.live-tv.spec index 4b27b9c..3d06fc2 100644 --- a/packaging/org.tizen.live-tv.spec +++ b/packaging/org.tizen.live-tv.spec @@ -13,7 +13,9 @@ BuildRequires: pkgconfig(ecore) BuildRequires: pkgconfig(edje) BuildRequires: pkgconfig(app-utils) BuildRequires: pkgconfig(vconf) +BuildRequires: pkgconfig(glib-2.0) BuildRequires: pkgconfig(gobject-2.0) +BuildRequires: pkgconfig(tv-service) BuildRequires: gettext-devel BuildRequires: edje-bin diff --git a/src/main.c b/src/main.c index 6a846b1..8d82c86 100644 --- a/src/main.c +++ b/src/main.c @@ -129,36 +129,9 @@ static Evas_Object *_add_win(const char *name) evas_object_show(win); - trans = evas_object_rectangle_add(evas_object_evas_get(win)); - if (!trans) { - _ERR("Create transparent layer failed"); - evas_object_del(win); - return NULL; - } - - /* for transparent layer */ - evas_object_color_set(trans, 0, 0, 0, 0); - evas_object_render_op_set(trans, EVAS_RENDER_COPY); - elm_win_resize_object_add(win, trans); - evas_object_size_hint_weight_set(trans, - EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - evas_object_show(trans); - return win; } -int _set_tv_overlay(Evas_Object *win) -{ - int r; - Ecore_Wl_Window *wl_win; - - wl_win = elm_win_wl_window_get(win); - - r = tv_overlay_set(wl_win); - - return r; -} - static void _tv_signal_cb(void *data, int is_signal) { struct _appdata *ad; @@ -203,12 +176,6 @@ static void _resume(void *data) return; } } - - r = _set_tv_overlay(ad->win); - if (r < 0) { - _ERR("Set overlay failed"); - return; - } } static bool _create(void *data) @@ -249,13 +216,6 @@ static bool _create(void *data) return false; } - r = _set_tv_overlay(ad->win); - if (r < 0) { - _ERR("Set overlay failed"); - evas_object_del(win); - return false; - } - ad->win = win; tv_signal_cb_set(_tv_signal_cb, ad); -- 2.7.4 From 28e817858005618b97b456ea2a7723a757157d93 Mon Sep 17 00:00:00 2001 From: "jinwoo.shin" Date: Mon, 27 Jul 2015 18:42:48 +0900 Subject: [PATCH 13/16] Add status icon Change-Id: If34c36a43a57856a004ddfcb3432e9907e6911c2 Signed-off-by: jinwoo.shin --- data/view/channelinfo.edc | 218 +++++++++++++++++++++++++++++++++++++++++++--- data/view/error.edc | 8 +- include/define.h | 10 +-- src/view_channelinfo.c | 40 ++------- 4 files changed, 222 insertions(+), 54 deletions(-) diff --git a/data/view/channelinfo.edc b/data/view/channelinfo.edc index 3beca20..2c4b716 100644 --- a/data/view/channelinfo.edc +++ b/data/view/channelinfo.edc @@ -219,6 +219,34 @@ group { group { name, GRP_CHANNELINFO; + images { + image, "ic_thumbnail_favorite_01.png" COMP; + image, "ic_thumbnail_lock_01_foc.png" COMP; + image, "ic_thumbnail_lock_01_nor.png" COMP; + } + script { + public is_locked=0, is_favorite=0, is_focused=0; + + public set_states() { + new focused; + new locked; + new favorite; + + focused = get_int(is_focused); + locked = get_int(is_locked); + favorite = get_int(is_favorite); + + if (locked == 1) { + if (focused == 1) + run_program(PROGRAM:"do_focus_locked"); + else + run_program(PROGRAM:"do_locked"); + } + + if (favorite == 1) + run_program(PROGRAM:"do_favorite"); + } + } parts { part { name, "bg"; @@ -405,7 +433,7 @@ group { } part { name, PART_CHANNELINFO_STATUS; - type, SWALLOW; + type, SPACER; scale, 1; description { state, "default" 0.0; @@ -421,6 +449,115 @@ group { align, 1.0 0.0; fixed, 1 1; } + + part { + name, PART_CHANNELINFO_LOCKED; + type, IMAGE; + scale, 1; + description { + state, "default" 0.0; + image.normal, "ic_thumbnail_lock_01_nor.png"; + rel1.relative, 1.0 0.0; + rel2.relative, 1.0 0.0; + min, 0 0; + align, 1.0 0.0; + fixed, 1 1; + visible, 0; + } + description { + state, "visible" 0.0; + inherit, "default" 0.0; + min, 28 28; + visible, 1; + } + description { + state, "focused" 0.0; + inherit, "default" 0.0; + image.normal, "ic_thumbnail_lock_01_foc.png"; + min, 28 28; + visible, 1; + } + } + part { + name, "padding.channelinfo.locked"; + type, SPACER; + scale, 1; + description { + state, "default" 0.0; + rel1 { + to, PART_CHANNELINFO_LOCKED; + relative, 0.0 0.0; + } + rel2 { + to, PART_CHANNELINFO_LOCKED; + relative, 0.0 0.0; + } + min, 0 0; + align, 1.0 0.0; + fixed, 1 1; + } + description { + state, "visible" 0.0; + inherit, "default" 0.0; + min, 10 0; + } + description { + state, "focused" 0.0; + inherit, "default" 0.0; + min, 10 0; + } + } + part { + name, PART_CHANNELINFO_FAVORITE; + type, IMAGE; + scale, 1; + description { + state, "default" 0.0; + image.normal, "ic_thumbnail_favorite_01.png"; + rel1 { + to, "padding.channelinfo.locked"; + relative, 0.0 0.0; + } + rel2 { + to, "padding.channelinfo.locked"; + relative, 0.0 0.0; + } + min, 0 0; + align, 1.0 0.0; + fixed, 1 1; + visible, 0; + } + description { + state, "visible" 0.0; + inherit, "default" 0.0; + min, 28 28; + visible, 1; + } + } + part { + name, "padding.channelinfo.favorite"; + type, SPACER; + scale, 1; + description { + state, "default" 0.0; + rel1 { + to, PART_CHANNELINFO_FAVORITE; + relative, 0.0 0.0; + } + rel2 { + to, PART_CHANNELINFO_FAVORITE; + relative, 0.0 0.0; + } + min, 0 0; + align, 1.0 0.0; + fixed, 1 1; + } + description { + state, "visible" 0.0; + inherit, "default" 0.0; + min, 10 0; + } + } } } programs { @@ -428,6 +565,14 @@ group { name, "focused"; signal, SIGNAL_FOCUSED; source, SOURCE_ELM; + script { + set_int(is_focused, 1); + set_states(); + run_program(PROGRAM:"do_focused"); + } + } + program { + name, "do_focused"; action, STATE_SET "focused" 0.0; target, "bg"; target, PART_CHANNELINFO_CHANNEL; @@ -438,12 +583,74 @@ group { name, "unfocused"; signal, SIGNAL_UNFOCUSED; source, SOURCE_ELM; + script { + set_int(is_focused, 0); + set_states(); + run_program(PROGRAM:"do_unfocused"); + } + } + program { + name, "do_unfocused"; action, STATE_SET "default" 0.0; target, "bg"; target, PART_CHANNELINFO_CHANNEL; target, PART_CHANNELINFO_TITLE; target, PART_CHANNELINFO_TIME; } + program { + name, "reset"; + signal, SIGNAL_RESET; + source, SOURCE_PROGRAM; + script { + set_int(is_locked, 0); + set_int(is_favorite, 0); + run_program(PROGRAM:"do_reset"); + } + } + program { + name, "do_reset"; + action, STATE_SET "default" 0.0; + target, PART_CHANNELINFO_FAVORITE; + target, "padding.channelinfo.favorite"; + target, PART_CHANNELINFO_LOCKED; + target, "padding.channelinfo.locked"; + } + program { + name, "set_locked"; + signal, SIGNAL_LOCKED; + source, SOURCE_PROGRAM; + script { + set_int(is_locked, 1); + set_states(); + } + } + program { + name, "set_favorite"; + signal, SIGNAL_FAVORITE; + source, SOURCE_PROGRAM; + script { + set_int(is_favorite, 1); + set_states(); + } + } + program { + name, "do_favorite"; + action, STATE_SET "visible" 0.0; + target, PART_CHANNELINFO_FAVORITE; + target, "padding.channelinfo.favorite"; + } + program { + name, "do_locked"; + action, STATE_SET "visible" 0.0; + target, PART_CHANNELINFO_LOCKED; + target, "padding.channelinfo.locked"; + } + program { + name, "do_focus_locked"; + action, STATE_SET "focused" 0.0; + target, PART_CHANNELINFO_LOCKED; + target, "padding.channelinfo.locked"; + } } } @@ -551,15 +758,6 @@ group { } } 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; diff --git a/data/view/error.edc b/data/view/error.edc index 2d1b3e9..18d4bf6 100644 --- a/data/view/error.edc +++ b/data/view/error.edc @@ -50,12 +50,12 @@ group { rel2.relative, 1.0 0.0; text { font, FONT_LIGHT; - size, 28; + size, 36; align, 0.5 0.5; min, 1 0; ellipsis, -1; } - color, 103 103 103 255; + color, 228 51 51 255; min, 0 36; align, 0.5 0.0; fixed, 1 1; @@ -71,12 +71,12 @@ group { text { font, FONT_LIGHT; size, 28; - align, 0.5 0.5; + align, 0.5 1.0; min, 1 0; ellipsis, -1; } color, 116 116 116 255; - min, 0 36; + min, 0 48; align, 0.5 1.0; fixed, 1 1; } diff --git a/include/define.h b/include/define.h index aedb0e9..94c2c4b 100644 --- a/include/define.h +++ b/include/define.h @@ -29,8 +29,11 @@ #define SIGNAL_FOCUSED "elm,action,focus" #define SIGNAL_UNFOCUSED "elm,action,unfocus" +#define SIGNAL_RESET "elm,action,reset" #define SIGNAL_FIRST "elm,state,first" #define SIGNAL_LAST "elm,state,last" +#define SIGNAL_LOCKED "elm,state,locked" +#define SIGNAL_FAVORITE "elm,state,favorite" #define FONT_REGULAR "TizenSans" #define FONT_LIGHT "TizenSans:style=Light" @@ -45,11 +48,6 @@ #define COLOR_OPTION_TEXT_FOCUSED 255 255 255 255 #define COLOR_OPTION_BORDER 154 154 154 255 -#define IMG_LOCKED_NOR IMAGEDIR"ic_thumbnail_lock_01_nor.png" -#define IMG_LOCKED_FOC IMAGEDIR"ic_thumbnail_lock_01_foc.png" -#define IMG_FAVORITE_NOR IMAGEDIR"ic_thumbnail_favorite_01.png" -#define IMG_FAVORITE_FOC IMG_FAVORITE_NOR - #define VIEW_CHANNELINFO "VIEW_CHANNELINFO" #define LAYOUT_CHANNELINFO "LAYOUT_CHANNELINFO" #define LAYOUT_CHANNELINFO_LIST "LAYOUT_CHANNELINFO_LIST" @@ -68,6 +66,8 @@ #define PART_CHANNELINFO_TITLE "part.channelinfo.title" #define PART_CHANNELINFO_TIME "part.channelinfo.time" #define PART_CHANNELINFO_STATUS "part.channelinfo.status" +#define PART_CHANNELINFO_LOCKED "part.channelinfo.locked" +#define PART_CHANNELINFO_FAVORITE "part.channelinfo.favorite" #define VIEW_CHANNELNUMBER "VIEW_CHANNELNUMBER" #define GRP_VIEW_CHANNELNUMBER "grp.view.channelnumber" diff --git a/src/view_channelinfo.c b/src/view_channelinfo.c index a9fb0cd..0bd6426 100644 --- a/src/view_channelinfo.c +++ b/src/view_channelinfo.c @@ -159,45 +159,15 @@ static void _stop_hide_timer(struct _priv *priv) } } -static void _add_icon(Evas_Object *box, const char *file) -{ - Evas_Object *ic; - - ic = elm_icon_add(box); - if (!ic) { - _ERR("failed to create icon"); - return; - } - - elm_image_file_set(ic, file, NULL); - elm_image_resizable_set(ic, EINA_FALSE, EINA_FALSE); - elm_image_no_scale_set(ic, EINA_TRUE); - evas_object_show(ic); - - elm_box_pack_end(box, ic); -} - -static void _pack_icon_box(Evas_Object *obj, +static void _set_icon_box(Evas_Object *obj, const struct tv_channel_info *channel_info) { - Evas_Object *box; - - box = elm_box_add(obj); - if (!box) { - _ERR("failed to create box"); - return; - } - evas_object_size_hint_weight_set(box, EVAS_HINT_EXPAND, - EVAS_HINT_EXPAND); - elm_box_horizontal_set(box, EINA_TRUE); - elm_box_padding_set(box, STATUS_BOX_PADDING, 0); - elm_box_align_set(box, 1.0, 0.5); - elm_object_part_content_set(obj, PART_CHANNELINFO_STATUS, box); + elm_object_signal_emit(obj, SIGNAL_RESET, SOURCE_PROGRAM); if (channel_info->locked) - _add_icon(box, IMG_LOCKED_NOR); + elm_object_signal_emit(obj, SIGNAL_LOCKED, SOURCE_PROGRAM); if (channel_info->favorite) - _add_icon(box, IMG_FAVORITE_NOR); + elm_object_signal_emit(obj, SIGNAL_FAVORITE, SOURCE_PROGRAM); } static void _load_channel_text(Evas_Object *obj, @@ -290,7 +260,7 @@ void draw_channel_info(Evas_Object *obj, UPDATE_TYPE_TIMER, (void *)STOP_HIDE_TIMER); _load_channel_text(obj, channel_info); - _pack_icon_box(obj, channel_info); + _set_icon_box(obj, channel_info); prog_req = calloc(1, sizeof(*prog_req)); prog_req->tv_program_cb = _tv_program_cb; -- 2.7.4 From 72e71c2d3332bd554f4a664f593b50344bd8ca3f Mon Sep 17 00:00:00 2001 From: "jinwoo.shin" Date: Tue, 28 Jul 2015 21:42:05 +0900 Subject: [PATCH 14/16] Add no channel/signal event Signed-off-by: jinwoo.shin Change-Id: I4a4ff705e6a259d2567ec706947f9d538884c733 --- data/view/channelnumber.edc | 5 ++++ src/main.c | 60 +++++++++++++++++++++++++++++++++++++-------- 2 files changed, 55 insertions(+), 10 deletions(-) diff --git a/data/view/channelnumber.edc b/data/view/channelnumber.edc index 387b8f7..48d9e02 100644 --- a/data/view/channelnumber.edc +++ b/data/view/channelnumber.edc @@ -174,6 +174,7 @@ group { } min, 216 224; align, 0.0 0.0; + fixed, 1 1; } } } @@ -281,6 +282,7 @@ group { color, COLOR_OPTION_BORDER; min, 0 1; align, 0.0 0.0; + fixed, 0 1; visible, 0; } description { @@ -306,6 +308,7 @@ group { color, COLOR_OPTION_BORDER; min, 1 0; align, 0.0 0.0; + fixed, 1 0; } } part { @@ -325,6 +328,7 @@ group { color, COLOR_OPTION_BORDER; min, 0 1; align, 0.0 1.0; + fixed, 0 1; visible, 0; } description { @@ -350,6 +354,7 @@ group { color, COLOR_OPTION_BORDER; min, 1 0; align, 1.0 0.0; + fixed, 1 0; } } } diff --git a/src/main.c b/src/main.c index 8d82c86..0b97768 100644 --- a/src/main.c +++ b/src/main.c @@ -36,6 +36,7 @@ struct _appdata { Ecore_Event_Handler *key_up; int is_signal; + int is_channel; }; struct key_map { @@ -64,9 +65,19 @@ static struct key_map g_kmap[] = { static Eina_Bool _key_down_cb(void *data, int type, void *ei) { + struct _appdata *ad; Evas_Event_Key_Down *ev = ei; size_t i, j; + if (!data) { + _ERR("failed to get data"); + return false; + } + + ad = data; + if (!ad->is_channel) + return ECORE_CALLBACK_DONE; + if (!strcmp(ev->keyname, KEY_ENTER) || !strcmp(ev->keyname, KEY_ENTER_REMOTE)) { if (viewmgr_active_view_count() > 0) @@ -90,9 +101,19 @@ static Eina_Bool _key_down_cb(void *data, int type, void *ei) static Eina_Bool _key_up_cb(void *data, int type, void *ei) { + struct _appdata *ad; Evas_Event_Key_Up *ev = ei; size_t i, j; + if (!data) { + _ERR("failed to get data"); + return false; + } + + ad = data; + if (!ad->is_channel) + return ECORE_CALLBACK_DONE; + if (!strcmp(ev->keyname, KEY_ENTER) || !strcmp(ev->keyname, KEY_ENTER_REMOTE)) { if (viewmgr_active_view_count() > 0) @@ -116,7 +137,7 @@ static Eina_Bool _key_up_cb(void *data, int type, void *ei) static Evas_Object *_add_win(const char *name) { - Evas_Object *win, *trans; + Evas_Object *win; win = elm_win_add(NULL, name, ELM_WIN_BASIC); if (!win) { @@ -147,6 +168,13 @@ static void _tv_signal_cb(void *data, int is_signal) return; ad->is_signal = is_signal; + + if (is_signal) { + viewmgr_hide_view(VIEW_ERROR); + } else { + viewmgr_show_view(VIEW_ERROR); + viewmgr_update_view(VIEW_ERROR, UPDATE_TYPE_NOSIGNAL, NULL); + } } static void _pause(void *data) @@ -155,7 +183,6 @@ static void _pause(void *data) static void _resume(void *data) { - struct _appdata *ad; int r; if (!data) { @@ -163,8 +190,6 @@ static void _resume(void *data) return; } - ad = data; - r = tv_resume(); if (r < 0) { _ERR("Resume tv service failed"); @@ -220,9 +245,9 @@ static bool _create(void *data) tv_signal_cb_set(_tv_signal_cb, ad); ad->key_down = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, - _key_down_cb, NULL); + _key_down_cb, ad); ad->key_up = ecore_event_handler_add(ECORE_EVENT_KEY_UP, - _key_up_cb, NULL); + _key_up_cb, ad); elm_config_focus_move_policy_set(ELM_FOCUS_MOVE_POLICY_IN); @@ -260,6 +285,7 @@ static void _terminate(void *data) static void _control(app_control_h control, void *data) { + struct _appdata *ad; char *svcid; int r; @@ -268,15 +294,29 @@ static void _control(app_control_h control, void *data) return; } + ad = data; + r = app_control_get_extra_data(control, KEY_SVCID, &svcid); if (r == SERVICE_ERROR_NONE) { - tv_channel_tune_with_service_id(atoll(svcid)); + r = tv_channel_tune_with_service_id(atoll(svcid)); free(svcid); - } else { - tv_channel_tune(); + if (!r) { + ad->is_channel = true; + viewmgr_show_view(VIEW_CHANNELINFO); + return; + } } - viewmgr_show_view(VIEW_CHANNELINFO); + r = tv_channel_tune(); + + if (r < 0) { + ad->is_channel = false; + viewmgr_show_view(VIEW_ERROR); + viewmgr_update_view(VIEW_ERROR, UPDATE_TYPE_NOCHANNEL, NULL); + } else { + ad->is_channel = true; + viewmgr_show_view(VIEW_CHANNELINFO); + } } int main(int argc, char *argv[]) -- 2.7.4 From 483bf077efe0370b7804559b1f0c31609747557b Mon Sep 17 00:00:00 2001 From: "jinwoo.shin" Date: Thu, 30 Jul 2015 16:23:22 +0900 Subject: [PATCH 15/16] Improve of showing channel program Change-Id: I3205f79b3df2bb73d4cb9fd801dd861e663b7e21 Signed-off-by: jinwoo.shin --- include/define.h | 2 +- src/layout_channelinfo_list.c | 2 ++ src/tv.c | 1 + src/view_channelinfo.c | 19 ++++++++++++++----- 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/include/define.h b/include/define.h index 94c2c4b..ed6f92c 100644 --- a/include/define.h +++ b/include/define.h @@ -19,7 +19,7 @@ #include "strings.h" -#define KEY_SVCID "svcid" +#define KEY_SVCID "service_id" #define PART_CONTENT "elm.swallow.content" #define PART_TEXT "elm.text" diff --git a/src/layout_channelinfo_list.c b/src/layout_channelinfo_list.c index a6ab0b9..89d71ff 100644 --- a/src/layout_channelinfo_list.c +++ b/src/layout_channelinfo_list.c @@ -306,6 +306,8 @@ static void _update(void *layout_data, int type, void *data) priv->channel_info->service_id); if (r < 0) _ERR("failed to tune next channel"); + + _update_channel_info(priv); } } } diff --git a/src/tv.c b/src/tv.c index b0da082..9685aa2 100644 --- a/src/tv.c +++ b/src/tv.c @@ -335,6 +335,7 @@ int tv_epg_get_program(int service_id, struct tv_program_request *request) (TvServiceEpgCallback) _tv_epg_event_cb, request); if (r != TVS_ERROR_OK) { _ERR("failed to get epg get current program : %d", service_id); + free(request); return -1; } diff --git a/src/view_channelinfo.c b/src/view_channelinfo.c index 0bd6426..14e2960 100644 --- a/src/view_channelinfo.c +++ b/src/view_channelinfo.c @@ -201,7 +201,11 @@ static void _load_program_info(Evas_Object *obj, const struct tv_program_info *prog) { char buf[BUF_MAX]; - int r; + int r, service_id; + + service_id = evas_object_data_get(obj, KEY_SVCID); + if (service_id != prog->service_id) + return; if (prog->start_time && prog->end_time) { r = _get_program_time(buf, sizeof(buf), @@ -261,16 +265,21 @@ void draw_channel_info(Evas_Object *obj, _load_channel_text(obj, channel_info); _set_icon_box(obj, channel_info); + evas_object_data_set(obj, KEY_SVCID, channel_info->service_id); prog_req = calloc(1, sizeof(*prog_req)); prog_req->tv_program_cb = _tv_program_cb; prog_req->user_data = obj; - if (channel_info->service_id == current_service) + r = tv_epg_get_cache_program(channel_info->service_id, + prog_req); + + if (channel_info->service_id == current_service) { + prog_req = calloc(1, sizeof(*prog_req)); + prog_req->tv_program_cb = _tv_program_cb; + prog_req->user_data = obj; r = tv_epg_get_program(channel_info->service_id, prog_req); - else - r = tv_epg_get_cache_program(channel_info->service_id, - prog_req); + } if (r < 0) viewmgr_update_view(VIEW_CHANNELINFO, -- 2.7.4 From d0de120f63d567bae3bb5d2395553a02adf32577 Mon Sep 17 00:00:00 2001 From: "jinwoo.shin" Date: Wed, 5 Aug 2015 11:27:36 +0900 Subject: [PATCH 16/16] Add tv overlay control code Change-Id: I75822764cce2c24baf127eb88a462142c00bb2a2 Signed-off-by: jinwoo.shin --- CMakeLists.txt | 4 +- packaging/org.tizen.live-tv.spec | 1 + src/main.c | 56 ++- src/tv.c | 9 + src/tv_service.c | 776 --------------------------------------- src/view_channelinfo.c | 4 +- 6 files changed, 69 insertions(+), 781 deletions(-) delete mode 100644 src/tv_service.c diff --git a/CMakeLists.txt b/CMakeLists.txt index de9e819..7f570a9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -66,9 +66,9 @@ pkg_check_modules(PKGS REQUIRED capi-appfw-application app-utils vconf - glib-2.0 gobject-2.0 - tv-service) + tv-service + tzsh-tvsrv) FOREACH(flag ${PKGS_CFLAGS}) SET(EXTRA_CFLGAS "${EXTRA_CFLGAS} ${flag}") diff --git a/packaging/org.tizen.live-tv.spec b/packaging/org.tizen.live-tv.spec index 3d06fc2..56819b1 100644 --- a/packaging/org.tizen.live-tv.spec +++ b/packaging/org.tizen.live-tv.spec @@ -16,6 +16,7 @@ BuildRequires: pkgconfig(vconf) BuildRequires: pkgconfig(glib-2.0) BuildRequires: pkgconfig(gobject-2.0) BuildRequires: pkgconfig(tv-service) +BuildRequires: pkgconfig(tzsh-tvsrv) BuildRequires: gettext-devel BuildRequires: edje-bin diff --git a/src/main.c b/src/main.c index 0b97768..0ea7cda 100644 --- a/src/main.c +++ b/src/main.c @@ -19,6 +19,7 @@ #include #include #include +#include #include "define.h" #include "tv.h" @@ -34,6 +35,8 @@ struct _appdata { Evas_Object *win; Ecore_Event_Handler *key_down; Ecore_Event_Handler *key_up; + tzsh_h tzsh; + tzsh_tvsrv_h ta; int is_signal; int is_channel; @@ -144,7 +147,7 @@ static Evas_Object *_add_win(const char *name) _ERR("elm_win_add failed"); return NULL; } - elm_win_alpha_set(win, EINA_FALSE); + elm_win_alpha_set(win, EINA_TRUE); elm_win_focus_highlight_enabled_set(win, EINA_FALSE); elm_win_focus_highlight_style_set(win, "invisible"); @@ -153,6 +156,27 @@ static Evas_Object *_add_win(const char *name) return win; } +static tzsh_tvsrv_h _bind_win(Evas_Object *win, tzsh_h tzsh) +{ + tzsh_window tz_win; + tzsh_tvsrv_h ta; + + tz_win = elm_win_window_id_get(win); + if (!tz_win) { + _ERR("failed to get window ID"); + return NULL; + } + + ta = tzsh_tvsrv_create(tzsh, tz_win); + if (!ta) { + _ERR("failed to create tvsrv"); + return NULL; + } + tzsh_tvsrv_bind(ta); + + return ta; +} + static void _tv_signal_cb(void *data, int is_signal) { struct _appdata *ad; @@ -179,10 +203,16 @@ static void _tv_signal_cb(void *data, int is_signal) static void _pause(void *data) { + int r; + + r = tv_pause(); + if (r < 0) + _ERR("Pause tv service failed"); } static void _resume(void *data) { + struct _appdata *ad; int r; if (!data) { @@ -190,6 +220,8 @@ static void _resume(void *data) return; } + ad = data; + r = tv_resume(); if (r < 0) { _ERR("Resume tv service failed"); @@ -201,6 +233,9 @@ static void _resume(void *data) return; } } + + if (ad->win) + elm_win_activate(ad->win); } static bool _create(void *data) @@ -218,12 +253,25 @@ static bool _create(void *data) elm_theme_overlay_add(NULL, THEMEFILE); + ad->tzsh = tzsh_create(TZSH_TOOLKIT_TYPE_EFL); + if (!ad->tzsh) { + _ERR("failed to create tzsh"); + return false; + } + win = _add_win(ad->name); if (!win) { _ERR("failed to create win object"); return false; } + ad->ta = _bind_win(win, ad->tzsh); + if (!ad->ta) { + _ERR("failed to bind win object"); + evas_object_del(win); + return false; + } + if (!viewmgr_create(win)) { _ERR("failed to initialize viewmgr"); evas_object_del(win); @@ -280,6 +328,12 @@ static void _terminate(void *data) evas_object_del(ad->win); ad->win = NULL; + + if (ad->ta) + tzsh_tvsrv_destroy(ad->ta); + + if (ad->tzsh) + tzsh_destroy(ad->tzsh); } } diff --git a/src/tv.c b/src/tv.c index 9685aa2..10b9bef 100644 --- a/src/tv.c +++ b/src/tv.c @@ -1121,6 +1121,15 @@ err: */ int tv_pause(void) { + int r; + + if (g_tv_info.live_svc) { + r = tv_service_live_destroy(g_tv_info.live_svc); + if (r != TVS_ERROR_OK) + _ERR("failed to destroy live service"); + g_tv_info.live_svc = NULL; + } + return 0; } diff --git a/src/tv_service.c b/src/tv_service.c deleted file mode 100644 index ee44fac..0000000 --- a/src/tv_service.c +++ /dev/null @@ -1,776 +0,0 @@ -/* - * Copyright (c) 2014 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include - -#include "tv.h" -#include "tv_service.h" - -#define DEFAULT_TIMER_INTERVAL 1.0 -#define TVS_VOLUME_MIN 0.0 -#define TVS_VOLUME_MAX 10.0 -#define TVS_PASSWORD "0000" - -#define VCONF_CHANNEL "db/menu/broadcasting/last_channel" - -struct dummy_tv_service_struct -{ - guint service_id; - TvServiceEpgCallback callback_func; - gpointer user_data; -}; - -struct _tv_service_info -{ - gdouble volume; - gboolean is_mute; -}; - -struct _tv_service_info tv_service_info; -GList *channel_list = NULL, *program_list = NULL; - -static void init_constant_channel_data(TvServiceChannel *channel) -{ - memset(channel, 0, sizeof(TvServiceChannel)); - - channel->frequency = 567000000; - channel->service_type = 2; - channel->channel_type = 0; - - channel->program_number = 1; - channel->source_id = 1; - // channel->stream_id = - channel->pcr_id = 17; - channel->minor = 1; - channel->vpid = 17; - // channel->apid = - channel->pmt_pid =16; - - channel->hide_guide = FALSE; - channel->hidden = FALSE; - channel->locked = FALSE; - channel->remembered = TRUE; - channel->save_by_psi = TRUE; - channel->digital = TRUE; - - channel->modulation_type = TVS_MODULATION_TYPE_8VSB; - channel->antenna_type = TV_SERVICE_ANTENNA_TYPE_CABLE; - channel->video_type = TVS_VIDEO_TYPE_MPEG2; - channel->audio_type = TVS_AUDIO_TYPE_AAC; -} - -/* Creates 3 programs for each channel (service_id) - * with one hour duration each. -*/ -static void init_program_data(int service_id, struct timeval tv) -{ - GList *epg_program_glist = NULL; - int i; - for (i = 0; i < 15; i++) - { - TvServiceEpgEventData *epg_data = NULL; - epg_data = (TvServiceEpgEventData *)g_malloc0 (sizeof(TvServiceEpgEventData)); - memset(epg_data, 0, sizeof(TvServiceEpgEventData)); - - epg_data->service_id = service_id; - // epg_data->event_id = - if (i == 0 && service_id % 2 == 0) - { - // Start first programs of some channels 30 minutes earlier than current time - // and substitute the difference with length - epg_data->start_time = tv.tv_sec - 30 * 60; - epg_data->length_in_seconds = 90 * 60; - } else { - epg_data->start_time = tv.tv_sec + i * 60 * 60; - epg_data->length_in_seconds = 60 * 60; - } - epg_data->etm_location= 1; - snprintf(epg_data->title_text, 255, "Awesome Program %d", i + 1); - snprintf(epg_data->extended_text, 255, "Description of Awesome Program %d", i + 1); - epg_data->current_time = tv.tv_sec; - epg_program_glist = g_list_append (epg_program_glist, epg_data); - } - program_list = g_list_append(program_list, (gpointer)epg_program_glist); -} - -static void init_data() -{ - struct timeval tv; - gettimeofday(&tv, NULL); - int i; - for (i = 1; i < 6; i++) - { - TvServiceChannel *channel = NULL; - channel = (TvServiceChannel *)g_malloc0(sizeof(TvServiceChannel)); - init_constant_channel_data(channel); - channel->service_id = i; - channel->major = (10 + i); - channel->favorite = i % 2 == 0 ? TRUE : FALSE; - snprintf(channel->program_name, PROGRAM_NAME_MAX_LEN - 1, "Super Channel %d", i); - channel_list = g_list_append(channel_list, (gpointer)channel); - init_program_data(i, tv); - } - - tv_service_info.volume = TVS_VOLUME_MAX / 2; - tv_service_info.is_mute = FALSE; -} - -/* 9 */ -gint tv_service_live_get_service_id(TvServiceLive live, gint *service_id) -{ - TvServiceLiveData *live_proxy; - - if (!live || !service_id) - return TVS_ERROR_NOT_AVAILABLE; - - live_proxy = (TvServiceLiveData *)live; - *service_id = live_proxy->service_id; - - _DBG("service_id = %d", *service_id); - - return TVS_ERROR_OK; -} - -/* 10 */ -gint tv_service_get_channel(gint service_id, TvServiceChannel *channel) -{ - _DBG("service_id = %d", service_id); - if (service_id < 1 || g_list_length(channel_list) < service_id) - return TVS_ERROR_NOT_AVAILABLE; - - TvServiceChannel *local_channel = NULL; - local_channel = (TvServiceChannel *)g_list_nth_data(channel_list, service_id - 1); - memcpy(channel, local_channel, sizeof(TvServiceChannel)); - - return TVS_ERROR_OK; -} - -/* We intentionally make a new copy of the channel_list, - * because live-tv frees the list internally - */ -TvServiceChannel *first_match_channel = NULL; -static gint _get_channel_list(TvServiceChannelMode channel_mode, TvServiceAntenna antenna_type, GList **channels, - GList *filter, TvServiceChannelSortType sort_type) -{ - GList *tmp_list = NULL; - TvServiceChannel *from, *to; - int i, size = g_list_length(channel_list); - if (filter == NULL) - { - // return the whole list - for (i = 0; i < size; i++) - { - from = g_list_nth_data(channel_list, i); - to = (TvServiceChannel *)malloc(sizeof(TvServiceChannel)); - memcpy(to, from, sizeof(TvServiceChannel)); - tmp_list = g_list_append(tmp_list, to); - } - *channels = tmp_list; - return TVS_ERROR_OK; - } - - TvServiceFilterNode *filter_node; - // FIXME: g_list_length(filter) is always 1, why? - filter_node = g_list_nth_data(filter, 0); - switch (filter_node->attribute) - { - case TV_SERVICE_CHANNEL_DATA_MAJOR_NUMBER: - case TV_SERVICE_CHANNEL_DATA_MINOR_NUMBER: - if (filter_node->match_type == CHANNEL_FILTER_MATCH_CONTAIN) - { - _DBG("CHANNEL_FILTER_MATCH_CONTAIN"); - gchar *str_value; - str_value = (gchar *)g_value_get_string((const GValue *)filter_node->value); - gulong gul_major_minor; - int length; - for (i = 0; i < size; i++) - { - from = g_list_nth_data(channel_list, i); - gul_major_minor = filter_node->attribute == TV_SERVICE_CHANNEL_DATA_MAJOR_NUMBER - ? from->major : from->minor; - length = snprintf(NULL, 0, "%lu", gul_major_minor); - char char_major_minor[length + 1]; - snprintf(char_major_minor, length + 1, "%lu", gul_major_minor); - if (strstr(char_major_minor, str_value)) - { - if (first_match_channel == NULL) - { - // reserve a copy for CHANNEL_FILTER_MATCH_EQUAL - first_match_channel = (TvServiceChannel *)malloc(sizeof(TvServiceChannel)); - memcpy(first_match_channel, from, sizeof(TvServiceChannel)); - } - to = (TvServiceChannel *)malloc(sizeof(TvServiceChannel)); - memcpy(to, from, sizeof(TvServiceChannel)); - tmp_list = g_list_append(tmp_list, to); - } - } - } - else - { - // FIXME: filter_node->value is always NULL at this point, why? - // gint *int_value; - // int_value = g_value_get_int(filter_node->value); - if (filter_node->match_type == CHANNEL_FILTER_MATCH_EQUAL) - { - _DBG("CHANNEL_FILTER_MATCH_EQUAL"); - if (first_match_channel) - { - tmp_list = g_list_append(tmp_list, first_match_channel); - first_match_channel = NULL; - } - } - else if (filter_node->match_type == CHANNEL_FILTER_MATCH_MORE) - { - _DBG("[NOT IMPLEMENTED YET] channel_filter_match_more"); - } - else if (filter_node->match_type == CHANNEL_FILTER_MATCH_LESS) - { - _DBG("[NOT IMPLEMENTED YET] channel_filter_match_less"); - } - else if (filter_node->match_type == CHANNEL_FILTER_MATCH_UNEQUAL) - { - _DBG("[NOT IMPLEMENTED YET] channel_filter_match_unequal"); - } - else - { - _ERR("match_type[%d] is out of range", filter_node->match_type); - return TVS_ERROR_PROCESS_FAIL; - } - } - break; - case TV_SERVICE_CHANNEL_DATA_SERVICE_ID: - case TV_SERVICE_CHANNEL_DATA_FREQUENCY: - case TV_SERVICE_CHANNEL_DATA_REMEMBERED: - case TV_SERVICE_CHANNEL_DATA_PROGRAM_NAME: - _DBG("case %d is not implemented yet", filter_node->attribute); - break; - default: - _ERR("attribute[%d] is out of range", filter_node->attribute); - return TVS_ERROR_PROCESS_FAIL; - } - - if (g_list_length(tmp_list) < 1) { - first_match_channel = NULL; - *channels = NULL; - return TVS_ERROR_PROCESS_FAIL; - } - *channels = tmp_list; - return TVS_ERROR_OK; -} - -gint tv_service_get_channel_list(TvServiceChannelMode mode, TvServiceAntenna antenna_type, GList **channels) -{ - _DBG(""); - return _get_channel_list(mode, antenna_type, channels, NULL, 0); -} - -gint tv_service_get_channel_list_ex(TvServiceChannelMode mode, TvServiceAntenna antenna_type, GList **channels, - GList *filter, TvServiceChannelSortType sort_type) -{ - _DBG(""); - return _get_channel_list(mode, antenna_type, channels, filter, sort_type); -} - -static Eina_Bool _tv_service_epg_get_current_program_cb(void *data) -{ - struct dummy_tv_service_struct *tvs_epg; - tvs_epg = data; - TvServiceEpgCallback callback_func = tvs_epg->callback_func; - callback_func(TVS_EPG_GET_CURRENT_PROGRAM, - g_list_nth_data(program_list, tvs_epg->service_id - 1), - tvs_epg->user_data); - free(tvs_epg); - - return ECORE_CALLBACK_CANCEL; -} - -/* 11 */ -gint tv_service_epg_get_current_program(TvServiceEpg epg, guint service_id, - TvServiceEpgCallback callback_func, gpointer user_data) -{ - _DBG("service_id = %d", service_id); - if (service_id < 1 || g_list_length(channel_list) < service_id) - { - return TVS_ERROR_NOT_AVAILABLE; - } - - struct dummy_tv_service_struct *tvs_epg; - tvs_epg = calloc(1, sizeof(*tvs_epg)); - tvs_epg->service_id = service_id; - tvs_epg->callback_func = callback_func; - tvs_epg->user_data = user_data; - ecore_timer_add(DEFAULT_TIMER_INTERVAL, _tv_service_epg_get_current_program_cb, tvs_epg); - - return TVS_ERROR_OK; -} - -gint tv_service_epg_get_cache_current_program(TvServiceEpg epg, guint service_id, - TvServiceEpgEventData *app_data) -{ - _DBG("service_id = %d", service_id); - if (service_id < 1 || g_list_length(channel_list) < service_id) - { - return TVS_ERROR_NOT_AVAILABLE; - } - struct timeval tv; - gettimeofday(&tv, NULL); - GList *prog_list = NULL; - prog_list = g_list_nth_data(program_list, service_id - 1); - TvServiceEpgEventData *epg_data = NULL; - gint result = TVS_ERROR_NOT_AVAILABLE; - int i; - for (i = 0; i < g_list_length(prog_list); i++) - { - epg_data = (TvServiceEpgEventData *)g_list_nth_data(prog_list, i); - if (epg_data == NULL) - { - continue; - } - if (epg_data->start_time <= tv.tv_sec && - epg_data->start_time + epg_data->length_in_seconds > tv.tv_sec) - { - app_data->service_id = epg_data->service_id; - app_data->event_id = epg_data->event_id; - app_data->start_time = epg_data->start_time; - app_data->etm_location = epg_data->etm_location; - app_data->length_in_seconds = epg_data->length_in_seconds; - g_stpcpy ((gchar *)app_data->title_text, (gchar *)epg_data->title_text); - g_stpcpy ((gchar *)app_data->extended_text, (gchar *)epg_data->extended_text); - app_data->current_time = tv.tv_sec; - result = TVS_ERROR_OK; - break; - } - } - - return result; -} - -gint tv_service_epg_get_program_list(TvServiceEpg epg, guint service_id, - guint start_time, guint duration, - TvServiceEpgCallback callback_func, gpointer user_data) -{ - _DBG("service_id = %d", service_id); - if (service_id < 1 || g_list_length(channel_list) < service_id) - { - return TVS_ERROR_NOT_AVAILABLE; - } - - struct dummy_tv_service_struct *tvs_epg; - tvs_epg = calloc(1, sizeof(*tvs_epg)); - tvs_epg->service_id = service_id; - tvs_epg->callback_func = callback_func; - tvs_epg->user_data = user_data; - ecore_timer_add(DEFAULT_TIMER_INTERVAL, _tv_service_epg_get_current_program_cb, tvs_epg); - - return TVS_ERROR_OK; -} - -/* 7 */ -gint tv_service_live_tune(TvServiceLive live, gint service_id) -{ - TvServiceLiveData *live_proxy; - - if (!live) - return TVS_ERROR_NOT_AVAILABLE; - - _DBG("service_id = %d", service_id); - if (service_id < 1 || g_list_length(channel_list) < service_id) - return TVS_ERROR_NOT_AVAILABLE; - - live_proxy = (TvServiceLiveData *)live; - live_proxy->service_id = service_id; - - vconf_set_int(VCONF_CHANNEL, service_id); - - return TVS_ERROR_OK; -} - -static gboolean _check_lock_unlock_password(gchar *password) -{ - if (g_strcmp0(TVS_PASSWORD, password)) - { - return FALSE; - } - return TRUE; -} - -gint tv_service_live_tune_locked_channel(TvServiceLive live, gint service_id, gchar * password) -{ - if (!live) - return TVS_ERROR_HANDLE_UNINITIALIZED; - - if (!password) { - _ERR("Password is NULL"); - return TVS_ERROR_INVALID_PARAMETER; - } - - if (service_id < 1 || g_list_length(channel_list) < service_id) - return TVS_ERROR_NOT_AVAILABLE; - - TvServiceChannel *channel = NULL; - channel = (TvServiceChannel *)g_list_nth_data(channel_list, service_id - 1); - if (!channel) - return TVS_ERROR_NOT_AVAILABLE; - - if (_check_lock_unlock_password(password)) - return TVS_ERROR_OK; - else - return TVS_ERROR_AUTHENTICATE_FAIL; -} - -gint tv_service_live_tune_up(TvServiceLive live, gint channel_mode, TvServiceAntenna antenna_type) -{ - TvServiceLiveData *live_proxy; - gint service_id; - - if (!live) - return TVS_ERROR_NOT_AVAILABLE; - - live_proxy = (TvServiceLiveData *)live; - service_id = (live_proxy->service_id) % g_list_length(channel_list) + 1; - - return tv_service_live_tune(live, service_id); -} - -gint tv_service_live_get_antenna_type(TvServiceLive live, TvServiceAntenna *type) -{ - _DBG(""); - TvServiceLiveData *live_proxy; - live_proxy = (TvServiceLiveData *)live; - *type = live_proxy->antenna_type; - - return TVS_ERROR_OK; -} - -/* 6 */ -gint tv_service_live_get_last_channel(gint *service_id) -{ - gint r = -1; - - r = vconf_get_int(VCONF_CHANNEL, service_id); - if (r < 0) - return TVS_ERROR_NOT_AVAILABLE; - - if ((*service_id) < 1) - return TVS_ERROR_NOT_AVAILABLE; - - return TVS_ERROR_OK; -} - -gint tv_service_live_tune_down(TvServiceLive live, gint channel_mode, - TvServiceAntenna antenna_type) -{ - TvServiceLiveData *live_proxy; - gint service_id; - - if (!live) - return TVS_ERROR_NOT_AVAILABLE; - - live_proxy = (TvServiceLiveData *)live; - service_id = live_proxy->service_id - 1; - if (service_id == 0) - service_id = g_list_length(channel_list); - - return tv_service_live_tune(live, service_id); -} - -gint tv_service_add_favorite_channel(gint service_id) -{ - TvServiceChannel *channel = NULL; - - if (service_id < 1 || g_list_length(channel_list) < service_id) - return TVS_ERROR_NOT_AVAILABLE; - - channel = (TvServiceChannel *) g_list_nth_data(channel_list, service_id - 1); - if (!channel) - return TVS_ERROR_NOT_AVAILABLE; - - channel->favorite = TRUE; - - return TVS_ERROR_OK; -} - -gint tv_service_delete_favorite_channel(gint service_id) -{ - TvServiceChannel *channel = NULL; - - if (service_id < 1 || g_list_length(channel_list) < service_id) - return TVS_ERROR_NOT_AVAILABLE; - - channel = (TvServiceChannel *) g_list_nth_data(channel_list, service_id - 1); - if (!channel) - return TVS_ERROR_NOT_AVAILABLE; - - channel->favorite = FALSE; - - return TVS_ERROR_OK; -} - -gint tv_service_add_channel(gint service_id) -{ - TvServiceChannel *channel = NULL; - - if (service_id < 1 || g_list_length(channel_list) < service_id) - return TVS_ERROR_NOT_AVAILABLE; - - channel = (TvServiceChannel *) g_list_nth_data(channel_list, service_id - 1); - if (!channel) - return TVS_ERROR_NOT_AVAILABLE; - - channel->remembered = TRUE; - - return TVS_ERROR_OK; -} - -gint tv_service_delete_channel(gint service_id) -{ - TvServiceChannel *channel = NULL; - - if (service_id < 1 || g_list_length(channel_list) < service_id) - return TVS_ERROR_NOT_AVAILABLE; - - channel = (TvServiceChannel *) g_list_nth_data(channel_list, service_id - 1); - if (!channel) - return TVS_ERROR_NOT_AVAILABLE; - - channel->remembered = FALSE; - - return TVS_ERROR_OK; -} - -gint tv_service_lock_channel(gint service_id, gchar *password) -{ - if (!password) - { - _ERR("Password is NULL"); - return TVS_ERROR_INVALID_PARAMETER; - } - if (service_id < 1 || g_list_length(channel_list) < service_id) - { - return TVS_ERROR_NOT_AVAILABLE; - } - TvServiceChannel *channel = NULL; - channel = (TvServiceChannel *)g_list_nth_data(channel_list, service_id - 1); - if (!channel) - { - return TVS_ERROR_NOT_AVAILABLE; - } - if (channel->locked) - { - // if channel is already locked, simply return success code - return TVS_ERROR_OK; - } - - if (_check_lock_unlock_password(password)) - { - channel->locked = TRUE; - return TVS_ERROR_OK; - } - - return TVS_ERROR_AUTHENTICATE_FAIL; -} - -gint tv_service_unlock_channel(gint service_id, gchar *password) -{ - if (!password) - { - _ERR("Password is NULL"); - return TVS_ERROR_INVALID_PARAMETER; - } - if (service_id < 1 || g_list_length(channel_list) < service_id) - { - return TVS_ERROR_NOT_AVAILABLE; - } - TvServiceChannel *channel = NULL; - channel = (TvServiceChannel *)g_list_nth_data(channel_list, service_id - 1); - if (!channel) - { - return TVS_ERROR_NOT_AVAILABLE; - } - if (!channel->locked) - { - // if channel is already unlocked, simply return success code - return TVS_ERROR_OK; - } - - if (_check_lock_unlock_password(password)) - { - channel->locked = FALSE; - return TVS_ERROR_OK; - } - - return TVS_ERROR_AUTHENTICATE_FAIL; -} - -gint tv_service_live_get_audio_mute(TvServiceLive live_svc, gboolean *mute) -{ - if (!live_svc) - return TVS_ERROR_HANDLE_UNINITIALIZED; - - if (!mute) - return TVS_ERROR_INVALID_PARAMETER; - - *mute = tv_service_info.is_mute; - - return TVS_ERROR_OK; -} - -gint tv_service_live_set_audio_mute(TvServiceLive live_svc, gboolean mute) -{ - if (!live_svc) - return TVS_ERROR_HANDLE_UNINITIALIZED; - - if (mute != TRUE && mute != FALSE) - return TVS_ERROR_INVALID_VALUE; - - tv_service_info.is_mute = mute; - - return TVS_ERROR_OK; -} - -gint tv_service_live_get_volume(TvServiceLive live_svc, gdouble *vol) -{ - if (!live_svc) - return TVS_ERROR_HANDLE_UNINITIALIZED; - - if (!vol) - return TVS_ERROR_INVALID_PARAMETER; - - *vol = tv_service_info.volume; - - return TVS_ERROR_OK; -} - -gint tv_service_live_set_volume(TvServiceLive live_svc, gdouble vol) -{ - if (!live_svc) - return TVS_ERROR_HANDLE_UNINITIALIZED; - - if (vol < TVS_VOLUME_MIN || vol > TVS_VOLUME_MAX) - return TVS_ERROR_INVALID_VALUE; - - tv_service_info.is_mute = FALSE; - tv_service_info.volume = vol; - - return TVS_ERROR_OK; -} - -/* 5 */ -/* 8 */ -gint tv_service_live_set_window_overlay(TvServiceLive live_svc, void *window_id) -{ - _DBG(""); - return 0; -} - -/* 1 */ -gint tv_service_live_create(TvServiceLive *live) -{ - _DBG(""); - init_data(); - TvServiceLiveData *local = NULL; - local = (TvServiceLiveData*)g_malloc0 (sizeof (TvServiceLiveData)); - // local->service_handle = - local->antenna_type = TV_SERVICE_ANTENNA_TYPE_CABLE; - local->service_id = -1; - // local->unique = - - local->tune_info.freq = 567000000; - local->tune_info.mod = 7; - // local->tune_info.apid = - local->tune_info.vpid = 17; - local->tune_info.ppid = 17; - local->tune_info.pro_num = 1; - - // local->call_back = - // local->user_data = - // local->window_id = - - *live = (TvServiceLive)local; - - return TVS_ERROR_OK; -} - -void _free_program_data(gpointer data) -{ - GList *epg_program_glist; - epg_program_glist = (GList *) data; - if (epg_program_glist) - g_list_free_full(epg_program_glist, (GDestroyNotify)g_free); -} - -gint tv_service_live_destroy(TvServiceLive live) -{ - _DBG(""); - g_list_free_full(program_list, (GDestroyNotify) _free_program_data); - g_list_free_full(channel_list, (GDestroyNotify)g_free); - - TvServiceLiveData *live_proxy; - live_proxy = (TvServiceLiveData *)live; - g_free (live_proxy); - live_proxy = NULL; - - return TVS_ERROR_OK; -} - -/* 2 */ -gint tv_service_live_register_callback(TvServiceLive live_svc, - void *_tv_service_event_cb, void *some_other_variable) -{ - _DBG(""); - return 0; -} - -/* 3 */ -gint tv_service_channel_info_create() -{ - _DBG(""); - return 0; -} - -gint tv_service_channel_info_destroy() -{ - _DBG(""); - return 0; -} - -/* 4 */ -gint tv_service_epg_create(TvServiceEpg * epg) -{ - _DBG(""); - EpgProxyData *proxy_data = NULL; - proxy_data = (EpgProxyData *)g_malloc0 (sizeof (EpgProxyData)); - // proxy_data->identity = identity; - proxy_data->event_list = NULL; - proxy_data->cb_flag = FALSE; - *epg = proxy_data; - - return TVS_ERROR_OK; -} - -gint tv_service_epg_destroy(TvServiceEpg epg) -{ - _DBG(""); - EpgProxyData *proxy_data = (EpgProxyData *)epg; - // g_object_unref (proxy_data->proxy); - g_list_free_full (proxy_data->event_list, (GDestroyNotify)g_free); - g_free (proxy_data); - - return TVS_ERROR_OK; -} diff --git a/src/view_channelinfo.c b/src/view_channelinfo.c index 14e2960..818e06d 100644 --- a/src/view_channelinfo.c +++ b/src/view_channelinfo.c @@ -203,7 +203,7 @@ static void _load_program_info(Evas_Object *obj, char buf[BUF_MAX]; int r, service_id; - service_id = evas_object_data_get(obj, KEY_SVCID); + service_id = (int) evas_object_data_get(obj, KEY_SVCID); if (service_id != prog->service_id) return; @@ -265,7 +265,7 @@ void draw_channel_info(Evas_Object *obj, _load_channel_text(obj, channel_info); _set_icon_box(obj, channel_info); - evas_object_data_set(obj, KEY_SVCID, channel_info->service_id); + evas_object_data_set(obj, KEY_SVCID, (void *)channel_info->service_id); prog_req = calloc(1, sizeof(*prog_req)); prog_req->tv_program_cb = _tv_program_cb; -- 2.7.4