From 0398000574135780958f3253e093ca0fca15bf77 Mon Sep 17 00:00:00 2001 From: "jinwoo.shin" Date: Tue, 21 Jul 2015 15:16:30 +0900 Subject: [PATCH 01/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 02/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 03/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 04/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 33cd2d0efd7eb0d49bd82d9dd8d0ceaec085b06a Mon Sep 17 00:00:00 2001 From: "jinwoo.shin" Date: Tue, 4 Aug 2015 22:08:03 +0900 Subject: [PATCH 05/16] Enable nodisplay configuration Change-Id: I0ccbee26eca49db84ffa52f4957e09723c27db65 Signed-off-by: jinwoo.shin --- org.tizen.live-tv.xml.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.tizen.live-tv.xml.in b/org.tizen.live-tv.xml.in index ae0c390..5c8c0fa 100644 --- a/org.tizen.live-tv.xml.in +++ b/org.tizen.live-tv.xml.in @@ -3,7 +3,7 @@ Jinwoo Shin Live TV application for Tizen TV - + @DESKTOP_ICON@ -- 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 06/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 From 7fdb859322266c712bfcda78b7cf2572aaa3d3e5 Mon Sep 17 00:00:00 2001 From: "jinwoo.shin" Date: Fri, 7 Aug 2015 17:23:52 +0900 Subject: [PATCH 07/16] Update channel number to handle minor channel Change-Id: Ib10babb5dfd89d887cbc3fb1da4b4b166a5102a2 Signed-off-by: jinwoo.shin --- data/view/channelnumber.edc | 10 +- include/tv_service.h | 281 -------------------------------------------- src/tv.c | 4 +- src/view_channelnumber.c | 48 ++++++-- 4 files changed, 45 insertions(+), 298 deletions(-) delete mode 100644 include/tv_service.h diff --git a/data/view/channelnumber.edc b/data/view/channelnumber.edc index 48d9e02..e1caabd 100644 --- a/data/view/channelnumber.edc +++ b/data/view/channelnumber.edc @@ -45,7 +45,7 @@ group { to, "padding.channelnumber"; relative, 1.0 1.0; } - min, 216 90; + min, 340 90; align, 0.0 0.0; fixed, 1 1; visible, 0; @@ -106,7 +106,7 @@ group { to_x, "part.channelnumber.channel_prefix"; relative, 1.0 1.0; } - min, 26 0; + min, 8 0; align, 0.0 0.0; fixed, 1 1; } @@ -170,9 +170,9 @@ group { } rel2 { to, "padding.list"; - relative, 1.0 1.0; + relative, 0.0 1.0; } - min, 216 224; + min, 292 224; align, 0.0 0.0; fixed, 1 1; } @@ -190,7 +190,7 @@ group { description { state, "default" 0.0; color, COLOR_BG_NORMAL; - min, 216 56; + min, 292 56; align, 0.0 0.0; } description { diff --git a/include/tv_service.h b/include/tv_service.h deleted file mode 100644 index bae9260..0000000 --- a/include/tv_service.h +++ /dev/null @@ -1,281 +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 - -#define TVS_EPG_CURRENT_TIME -1 -#define PROGRAM_NAME_MAX_LEN 25 -#define CHANNEL_FILTER_STRING_MAX_LEN 100 - -/** - * An enumeration. - * Enumeration for tv service error type - */ -typedef enum -{ - TVS_ERROR_OK = 0, /**< tv service error ok */ - TVS_ERROR_NO_FREE_MEMORY = -1, /**< tv service error no free memory */ - TVS_ERROR_HANDLE_UNINITIALIZED = -2, /**< tv service error handle uninitialized */ - TVS_ERROR_RPC_CALL_FAIL = -3, /**< tv service error rpc call fail */ - TVS_ERROR_INVALID_PARAMETER = -4, /**< tv service error invalid input parameter */ - TVS_ERROR_INVALID_VALUE = -5, /**< tv service error invalid input value */ - TVS_ERROR_NOT_AVAILABLE = -6, /**< tv service error not available */ - TVS_ERROR_SEQLITE_BUSY = -7, /**< tv service error SQLite busy */ - TVS_ERROR_PROCESS_FAIL = -8, /**< tv service error process error*/ - TVS_ERROR_DATABASE_FAIL = -9, /**< tv service error database query fail*/ - TVS_ERROR_AUTHENTICATE_FAIL = -10, /**< tv service error Authenticate fail, ex, lock password match fail*/ - TVS_ERROR_UNKNOWN = -255 /**< tv service error unknown */ -} TvServiceError; - -typedef enum -{ - TV_SERVICE_CHANNEL_MODE_UNDEFINED = -1, /* Unknown mode */ - TV_SERVICE_CHANNEL_MODE_ALL, /* ALL channel mode */ - TV_SERVICE_CHANNEL_MODE_DIGITAL, /* Digital channel mode */ - TV_SERVICE_CHANNEL_MODE_ANALOG, /* Analog channel mode */ - TV_SERVICE_CHANNEL_MODE_DIGITAL_ANALOG, /* Digital & Analog channel mode*/ - TV_SERVICE_CHANNEL_MODE_FAVORITE, /* Analog channel mode */ - TV_SERVICE_CHANNEL_MODE_ALL_DIGITAL_ANALOG /* Digital & Analog channel mode (include delete channel)*/ -} TvServiceChannelMode; - -/** - * An enumeration. - * Enumeration for channel list sort type. - */ -typedef enum -{ - CHANNEL_SORT_TYPE_MAJOR_MINOR_NUMBER = 0x0, - CHANNEL_SORT_TYPE_SERVICE_ID, - CHANNEL_SORT_TYPE_PROGRAM_NAME, - CHANNEL_SORT_TYPE_MAX -} TvServiceChannelSortType; - -typedef enum -{ - TV_SERVICE_LIVE_EVENT_BEGIN, /* live event tune start*/ - TV_SERVICE_LIVE_EVENT_TUNER_LOCK, /* live event tune lock result*/ - TV_SERVICE_LIVE_EVENT_CHANNEL_LOCK, /* live event channel lock(video and audio mute)*/ - TV_SERVICE_LIVE_EVENT_CHANNEL_UNLOCK, /* live event channel unlock*/ - TV_SERVICE_LIVE_EVENT_AUTO_DESTROY, /* live event auto destroy*/ - TV_SERVICE_LIVE_EVENT_RESOLUTION /* live event resolution*/ -} TvServiceLiveEvent; -typedef void (*TvServiceLiveCallback) (TvServiceLiveEvent event, gpointer user_data, const gpointer data); -typedef struct -{ - gint freq; /**the frequence*/ - gint mod; /**the modulation*/ - gint apid; /**the audio pid*/ - gint vpid; /**the videa pid*/ - gint ppid; /**the pmt pid*/ - gint pro_num; /**the program number*/ -} TvServiceLiveTuneInfo; - -typedef struct -{ - // TvServiceGenLive *proxy; /**the live proxy object*/ - guint service_handle; /**the live service handle*/ - gint antenna_type; /**antenna type*/ - gint service_id; /**service id*/ - gint unique; /**identify*/ - TvServiceLiveTuneInfo tune_info; /**tune info*/ - TvServiceLiveCallback call_back; /**the call back function*/ - gpointer user_data; /**the user_data*/ - gpointer window_id; /**the window id*/ -} TvServiceLiveData; - -typedef gpointer TvServiceLive; - -typedef void* TvServiceEpg; - -typedef enum -{ - TVS_EPG_CREATE = 0, - TVS_EPG_DESTROY, - TVS_EPG_GET_CURRENT_PROGRAM, - TVS_EPG_GET_PROGRAM_LIST, - TVS_EPG_AUTO_DESTROY, - TVS_EPG_DATA_UPDATED -} tvs_epg_event_e; - -typedef void (*TvServiceEpgCallback) (tvs_epg_event_e type, gpointer epg_data, gpointer user_data); - -typedef struct -{ - guint service_id; - guint event_id; - guint start_time; - guint etm_location; - guint length_in_seconds; - guint8 title_text[256]; - guint current_time; - guint8 extended_text[256]; -} TvServiceEpgEventData; - -typedef enum -{ - TVS_MODULATION_TYPE_UNKNOWN = -1, - TVS_MODULATION_TYPE_QPSK, - TVS_MODULATION_TYPE_16QAM, - TVS_MODULATION_TYPE_32QAM, - TVS_MODULATION_TYPE_64QAM, - TVS_MODULATION_TYPE_128QAM, - TVS_MODULATION_TYPE_256QAM, - TVS_MODULATION_TYPE_AUTO_QAM, - TVS_MODULATION_TYPE_8VSB, - TVS_MODULATION_TYPE_16VSB, - TVS_MODULATION_TYPE_8PSK, - TVS_MODULATION_TYPE_NTSC, - TVS_MODULATION_TYPE_PAL, - TVS_MODULATION_TYPE_MAX -} TvServiceModulationTpye; -typedef enum -{ - TV_SERVICE_ANTENNA_TYPE_UNDEFINED = -1, /* Unknown type */ - TV_SERVICE_ANTENNA_TYPE_AIR, /* Antenna air type */ - TV_SERVICE_ANTENNA_TYPE_CABLE, /* Antenna cable type */ - TV_SERVICE_ANTENNA_TYPE_ALL /*Antenna all type */ -} TvServiceAntenna; -typedef enum -{ - TVS_VIDEO_TYPE_UNKNOWN = -1, - TVS_VIDEO_TYPE_MPEG2 , - TVS_VIDEO_TYPE_H264, - TVS_VIDEO_TYPE_JPEG, - TVS_VIDEO_TYPE_AVS, - TVS_VIDEO_TYPE_MAX -} TvServiceVideoType; - -typedef enum -{ - TVS_AUDIO_TYPE_UNKNOWN = -1, - TVS_AUDIO_TYPE_AC3, - TVS_AUDIO_TYPE_MPEG2, - TVS_AUDIO_TYPE_AAC, - TVS_AUDIO_TYPE_HE_AAC, - TVS_AUDIO_TYPE_MAX -} TvServiceAudioType; -typedef struct -{ - guint service_id; - guint frequency; - guint service_type; - guint channel_type; - - gulong program_number; - gulong source_id; - gulong stream_id; - gulong pcr_id; - gulong major; - gulong minor; - gulong vpid; - gulong apid; - gulong pmt_pid; - - gboolean hide_guide; - gboolean hidden; - gboolean locked; - gboolean remembered; - gboolean save_by_psi; - gboolean digital; - gboolean favorite; - - gchar program_name[PROGRAM_NAME_MAX_LEN]; - - TvServiceModulationTpye modulation_type; - TvServiceAntenna antenna_type; - TvServiceVideoType video_type; - TvServiceAudioType audio_type; -} TvServiceChannel; - -typedef enum { - CHANNEL_FILTER_MATCH_NONE = 0, - CHANNEL_FILTER_MATCH_EQUAL, - CHANNEL_FILTER_MATCH_MORE, - CHANNEL_FILTER_MATCH_LESS, - CHANNEL_FILTER_MATCH_UNEQUAL, - CHANNEL_FILTER_MATCH_CONTAIN, - CHANNEL_FILTER_MATCH_MAX -} TvServiceChannelFilterMatchType; - -typedef enum { - TV_SERVICE_CHANNEL_DATA_NONE = 0, - TV_SERVICE_CHANNEL_DATA_SERVICE_ID, - TV_SERVICE_CHANNEL_DATA_FREQUENCY, - TV_SERVICE_CHANNEL_DATA_MAJOR_NUMBER, - TV_SERVICE_CHANNEL_DATA_MINOR_NUMBER, - TV_SERVICE_CHANNEL_DATA_PROGRAM_NAME, - TV_SERVICE_CHANNEL_DATA_REMEMBERED, - TV_SERVICE_CHANNEL_DATA_MAX -} TvServiceChannelDataAttr; - -typedef struct { - TvServiceChannelDataAttr attribute; - TvServiceChannelFilterMatchType match_type; - GValue *value; -} TvServiceFilterNode; - -typedef struct { - gint identity; - // TvServiceGenEpg *proxy; - TvServiceEpgCallback cb; - gboolean cb_flag; - gpointer user_data; - GList *event_list; -} EpgProxyData; - -typedef struct { - guint service_id; - guint start_time; - guint duration; - TvServiceEpgCallback event_callback; - gpointer event_callback_userdata; -} EpgProxyEventData; - -gint tv_service_live_get_service_id (TvServiceLive live, gint * service_id); -gint tv_service_get_channel (gint service_id, TvServiceChannel * channel); -gint tv_service_get_channel_list (TvServiceChannelMode mode, TvServiceAntenna type, GList ** channels); -gint tv_service_get_channel_list_ex (TvServiceChannelMode mode, TvServiceAntenna type, GList ** channels, - GList * filter, TvServiceChannelSortType sort_type); -gint tv_service_epg_get_current_program (TvServiceEpg epg, guint service_id, TvServiceEpgCallback callback_func, gpointer user_data); -gint tv_service_epg_get_cache_current_program (TvServiceEpg epg, guint service_id, TvServiceEpgEventData * app_data); -gint tv_service_epg_get_program_list (TvServiceEpg epg, guint service_id, guint start_time, guint duration, TvServiceEpgCallback callback_func, gpointer user_data); -gint tv_service_live_create (TvServiceLive * live); -gint tv_service_live_destroy (TvServiceLive live); -gint tv_service_live_tune_locked_channel (TvServiceLive live, gint service_id, gchar * password); -gint tv_service_epg_create (TvServiceEpg * epg); -gint tv_service_epg_destroy (TvServiceEpg epg); -gint tv_service_live_get_last_channel (gint * service_id); -gint tv_service_live_get_antenna_type (TvServiceLive live, TvServiceAntenna * type); -gint tv_service_live_tune (TvServiceLive live, gint service_id); -gint tv_service_lock_channel (gint service_id, gchar * password); -gint tv_service_unlock_channel (gint service_id, gchar * password); -gint tv_service_live_tune_down(TvServiceLive live, gint channel_mode, - TvServiceAntenna antenna_type); -gint tv_service_live_tune_up(TvServiceLive live, gint channel_mode, - TvServiceAntenna antenna_type); -gint tv_service_add_favorite_channel(gint service_id); -gint tv_service_delete_favorite_channel(gint service_id); -gint tv_service_add_channel(gint service_id); -gint tv_service_delete_channel(gint service_id); -gint tv_service_live_get_audio_mute(TvServiceLive live_svc, gboolean *mute); -gint tv_service_live_set_audio_mute(TvServiceLive live_svc, gboolean mute); -gint tv_service_live_get_volume(TvServiceLive live_svc, gdouble *vol); -gint tv_service_live_set_volume(TvServiceLive live_svc, gdouble vol); -gint tv_service_live_set_window_overlay(TvServiceLive live_svc, void *window_id); -gint tv_service_channel_info_create(); -gint tv_service_channel_info_destroy(); -gint tv_service_live_register_callback(TvServiceLive live_svc, - void *_tv_service_event_cb, void *some_other_variable); diff --git a/src/tv.c b/src/tv.c index 10b9bef..fdae39f 100644 --- a/src/tv.c +++ b/src/tv.c @@ -21,12 +21,14 @@ #include #include +#include +#include + #include #include #include "define.h" #include "tv.h" -#include "tv_service.h" #define DEFAULT_SERVICE 1 diff --git a/src/view_channelnumber.c b/src/view_channelnumber.c index 89048ca..6a63655 100644 --- a/src/view_channelnumber.c +++ b/src/view_channelnumber.c @@ -26,7 +26,8 @@ #define HIDE_DUR 3.0 #define BUF_MAX 128 -#define NUMBER_MAX 3 +#define INPUT_MAX 4 +#define NUMBER_MAX 2 struct _priv { Evas_Object *base; @@ -35,7 +36,7 @@ struct _priv { int major; int minor; - char number[NUMBER_MAX+1]; + char number[INPUT_MAX+1]; }; static void _key_down_cb(int id, void *data, Evas *e, Evas_Object *obj, @@ -184,9 +185,17 @@ static void _update_channel_list(struct _priv *priv) elm_object_focus_allow_set(ly, EINA_TRUE); - snprintf(buf, sizeof(buf), "%ld %s", - channel_info->channel_major, - channel_info->channel_name); + if (channel_info->channel_minor > 0 && + channel_info->channel_minor < MINOR_MAX) + snprintf(buf, sizeof(buf), "%lu-%lu %s", + channel_info->channel_major, + channel_info->channel_minor, + channel_info->channel_name); + else + snprintf(buf, sizeof(buf), "%lu %s", + channel_info->channel_major, + channel_info->channel_name); + elm_object_text_set(ly, buf); inputmgr_add_callback(ly, 0, &channel_handler, @@ -213,13 +222,23 @@ static void _update_channel_list(struct _priv *priv) static void _update_number_info(struct _priv *priv) { + char buf[BUF_MAX] = "\0"; + if (!priv->number) { _ERR("Wrong channel number"); return; } - elm_object_part_text_set(priv->base, - PART_CHANNELNUMBER_NUMBER, priv->number); + if (strlen(priv->number) > NUMBER_MAX) { + strncpy(buf, priv->number, NUMBER_MAX); + strncat(buf, "-", 1); + strncat(buf, priv->number + NUMBER_MAX, NUMBER_MAX); + elm_object_part_text_set(priv->base, + PART_CHANNELNUMBER_NUMBER, buf); + } else { + elm_object_part_text_set(priv->base, + PART_CHANNELNUMBER_NUMBER, priv->number); + } _update_channel_list(priv); } @@ -248,8 +267,9 @@ 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; + memset(priv->number, '\0', sizeof(char) * INPUT_MAX + 1); + priv->major = 0; + priv->minor = 0; _release_channel_handler(priv->list); elm_box_clear(priv->list); @@ -257,17 +277,23 @@ static void _number_reset(struct _priv *priv) static void _number_tuning(struct _priv *priv, const char *keyname) { + char buf[BUF_MAX] = "\0"; + if (!keyname) { _ERR("failed to get keyname"); return; } strncat(priv->number, keyname, 1); - priv->major = atoi(priv->number); + strncpy(buf, priv->number, INPUT_MAX); + + priv->minor = atoi(buf + NUMBER_MAX); + buf[NUMBER_MAX] = '\0'; + priv->major = atoi(buf); _update_number_info(priv); - if (strlen(priv->number) == NUMBER_MAX) + if (strlen(priv->number) >= INPUT_MAX) _done_input(priv); } -- 2.7.4 From 724d289f1b4adc82f12ac0537821904e00974c00 Mon Sep 17 00:00:00 2001 From: Minkyu Kang Date: Fri, 7 Aug 2015 21:47:50 +0900 Subject: [PATCH 08/16] add service file for launch automatically Change-Id: I93d228e81b0241ad4fb576d70c5c4411fec2bbbb Signed-off-by: Minkyu Kang --- packaging/org.tizen.live-tv.path | 5 +++++ packaging/org.tizen.live-tv.service | 5 +++++ packaging/org.tizen.live-tv.spec | 11 +++++++++++ src/main.c | 1 + 4 files changed, 22 insertions(+) create mode 100644 packaging/org.tizen.live-tv.path create mode 100644 packaging/org.tizen.live-tv.service diff --git a/packaging/org.tizen.live-tv.path b/packaging/org.tizen.live-tv.path new file mode 100644 index 0000000..74d8137 --- /dev/null +++ b/packaging/org.tizen.live-tv.path @@ -0,0 +1,5 @@ +[Unit] +Description=This path will tell you that live-tv is ready to launch + +[Path] +PathExists=/run/.wm_ready diff --git a/packaging/org.tizen.live-tv.service b/packaging/org.tizen.live-tv.service new file mode 100644 index 0000000..f4c73bc --- /dev/null +++ b/packaging/org.tizen.live-tv.service @@ -0,0 +1,5 @@ +[Unit] +Description=live-tv + +[Service] +ExecStart=/bin/sh -c -l '/usr/bin/aul_test launch org.tizen.live-tv' diff --git a/packaging/org.tizen.live-tv.spec b/packaging/org.tizen.live-tv.spec index 56819b1..13eec6d 100644 --- a/packaging/org.tizen.live-tv.spec +++ b/packaging/org.tizen.live-tv.spec @@ -5,6 +5,8 @@ Release: 1 Group: Applications License: Apache-2.0 Source0: %{name}-%{version}.tar.gz +Source1: %{name}.service +Source2: %{name}.path BuildRequires: cmake BuildRequires: pkgconfig(capi-appfw-application) @@ -26,6 +28,8 @@ BuildRequires: edje-bin %define _datadir %{_pkgdir}/data %define _edjedir %{_resdir}/edje %define _manifestdir %{_datarootdir}/packages +%define _sysuserdir /systemd/user +%define _servicedir /systemd/user/default.target.wants %description Live TV application for Tizen TV. @@ -47,6 +51,10 @@ make %{?jobs:-j%jobs} %install %make_install install --directory %{buildroot}/%{_datadir} +install --directory %{buildroot}%{_libdir}%{_servicedir} +install -m 0644 %{SOURCE1} %{buildroot}%{_libdir}%{_sysuserdir} +install -m 0644 %{SOURCE2} %{buildroot}%{_libdir}%{_sysuserdir} +ln -sf ../%{name}.path %{buildroot}%{_libdir}%{_servicedir} %clean rm -rf %{buildroot} @@ -57,3 +65,6 @@ rm -rf %{buildroot} %{_resdir}/* %{_datadir} %{_manifestdir}/%{name}.xml +%{_libdir}%{_sysuserdir}/%{name}.service +%{_libdir}%{_sysuserdir}/%{name}.path +%{_libdir}%{_servicedir}/%{name}.path diff --git a/src/main.c b/src/main.c index 0ea7cda..dc5ec16 100644 --- a/src/main.c +++ b/src/main.c @@ -147,6 +147,7 @@ static Evas_Object *_add_win(const char *name) _ERR("elm_win_add failed"); return NULL; } + elm_win_title_set(win, PACKAGE); elm_win_alpha_set(win, EINA_TRUE); elm_win_focus_highlight_enabled_set(win, EINA_FALSE); elm_win_focus_highlight_style_set(win, "invisible"); -- 2.7.4 From 29acd23c8d728d004fceb908a6abc84268b94aee Mon Sep 17 00:00:00 2001 From: Minkyu Kang Date: Sat, 8 Aug 2015 13:33:34 +0900 Subject: [PATCH 09/16] set window opaque state Change-Id: Icdb6e454a6b393817ccd6c1f88a5acd60c64675a Signed-off-by: Minkyu Kang --- CMakeLists.txt | 1 + packaging/org.tizen.live-tv.spec | 1 + src/main.c | 2 ++ 3 files changed, 4 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7f570a9..2bd285b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -64,6 +64,7 @@ pkg_check_modules(PKGS REQUIRED ecore edje capi-appfw-application + capi-ui-efl-util app-utils vconf gobject-2.0 diff --git a/packaging/org.tizen.live-tv.spec b/packaging/org.tizen.live-tv.spec index 13eec6d..2c11982 100644 --- a/packaging/org.tizen.live-tv.spec +++ b/packaging/org.tizen.live-tv.spec @@ -10,6 +10,7 @@ Source2: %{name}.path BuildRequires: cmake BuildRequires: pkgconfig(capi-appfw-application) +BuildRequires: pkgconfig(capi-ui-efl-util) BuildRequires: pkgconfig(elementary) BuildRequires: pkgconfig(ecore) BuildRequires: pkgconfig(edje) diff --git a/src/main.c b/src/main.c index dc5ec16..8dd2a2c 100644 --- a/src/main.c +++ b/src/main.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "define.h" #include "tv.h" @@ -151,6 +152,7 @@ static Evas_Object *_add_win(const char *name) elm_win_alpha_set(win, EINA_TRUE); elm_win_focus_highlight_enabled_set(win, EINA_FALSE); elm_win_focus_highlight_style_set(win, "invisible"); + efl_util_set_window_opaque_state(win, 1); evas_object_show(win); -- 2.7.4 From 3783fa6ee621448e0037b74bf9266990d99c76ff Mon Sep 17 00:00:00 2001 From: "jinwoo.shin" Date: Mon, 10 Aug 2015 11:33:02 +0900 Subject: [PATCH 10/16] Add exception handling on get last channel Change-Id: I834bc4142264dac5179edbaa12431653d811d932 Signed-off-by: jinwoo.shin --- src/tv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tv.c b/src/tv.c index fdae39f..804e964 100644 --- a/src/tv.c +++ b/src/tv.c @@ -668,7 +668,7 @@ int tv_channel_tune(void) } r = tv_service_live_get_last_channel(&service_id); - if (r < 0) { + if (r < 0 || service_id < 1) { _ERR("failed to get current service id"); service_id = DEFAULT_SERVICE; } -- 2.7.4 From d54d6e8a6b55bfc72e52efc183aac60bc2586d9d Mon Sep 17 00:00:00 2001 From: "jinwoo.shin" Date: Mon, 10 Aug 2015 14:05:45 +0900 Subject: [PATCH 11/16] Don't call live service destroy Change-Id: Ie3850b94f0229b24a947b4b1df64cc1d8ef1f2c3 Signed-off-by: jinwoo.shin --- src/tv.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/tv.c b/src/tv.c index 804e964..31bf9d1 100644 --- a/src/tv.c +++ b/src/tv.c @@ -1055,12 +1055,8 @@ int tv_destroy(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"); + if (g_tv_info.live_svc) g_tv_info.live_svc = NULL; - } r = tv_service_channel_info_destroy(); if (r < 0) -- 2.7.4 From 2d9c257ccc160095c3bf9a465ea2fa4f78294330 Mon Sep 17 00:00:00 2001 From: "jinwoo.shin" Date: Mon, 10 Aug 2015 15:44:04 +0900 Subject: [PATCH 12/16] Fix no signal banner is not shown Change-Id: I6d6f5b458fd954dc85c8c2bfc76243a640d7b14d Signed-off-by: jinwoo.shin --- src/main.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main.c b/src/main.c index 8dd2a2c..6616c90 100644 --- a/src/main.c +++ b/src/main.c @@ -191,9 +191,6 @@ static void _tv_signal_cb(void *data, int is_signal) ad = data; - if (ad->is_signal == is_signal) - return; - ad->is_signal = is_signal; if (is_signal) { -- 2.7.4 From 00781418fa5792d01af898fa9fd4efe90abde89b Mon Sep 17 00:00:00 2001 From: "jinwoo.shin" Date: Mon, 10 Aug 2015 16:16:34 +0900 Subject: [PATCH 13/16] Fix memory leak issue Change-Id: I7529da362671bbbf770b45a6bef8a33b7652f627 Signed-off-by: jinwoo.shin --- src/layout_channelinfo.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/layout_channelinfo.c b/src/layout_channelinfo.c index d74ce81..2771b12 100644 --- a/src/layout_channelinfo.c +++ b/src/layout_channelinfo.c @@ -65,6 +65,8 @@ static bool _create(layoutmgr *lmgr, void *data) layout = elm_layout_add(base); if (!layout) { _ERR("failed to create layout"); + free(priv); + return false; } if (!elm_layout_file_set(layout, EDJEFILE, GRP_CHANNELINFO)) -- 2.7.4 From 1481c623c2a6eb1ecc529a62c04ee89bafd72ec6 Mon Sep 17 00:00:00 2001 From: "jinwoo.shin" Date: Tue, 11 Aug 2015 21:13:38 +0900 Subject: [PATCH 14/16] Call live service pause/resume on app pause/resume Change-Id: I37a556b1c392bb18ceff005c5e35d96cf5fedac3 Signed-off-by: jinwoo.shin --- src/tv.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/tv.c b/src/tv.c index 804e964..ecf5049 100644 --- a/src/tv.c +++ b/src/tv.c @@ -1055,12 +1055,8 @@ int tv_destroy(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"); + if (g_tv_info.live_svc) g_tv_info.live_svc = NULL; - } r = tv_service_channel_info_destroy(); if (r < 0) @@ -1126,10 +1122,9 @@ int tv_pause(void) int r; if (g_tv_info.live_svc) { - r = tv_service_live_destroy(g_tv_info.live_svc); + r = tv_service_live_tune_pause(g_tv_info.live_svc); if (r != TVS_ERROR_OK) - _ERR("failed to destroy live service"); - g_tv_info.live_svc = NULL; + _ERR("failed to pause live service"); } return 0; @@ -1151,10 +1146,17 @@ int tv_resume(void) { int r; - if (g_tv_info.live_svc) - return 0; + if (!g_tv_info.live_svc) { + r = tv_service_live_create(&g_tv_info.live_svc); + if (r != TVS_ERROR_OK) { + _ERR("failed to create live service"); + goto err; + } else { + return 1; + } + } - r = tv_service_live_create(&g_tv_info.live_svc); + r = tv_service_live_tune_resume(g_tv_info.live_svc); if (r != TVS_ERROR_OK) { _ERR("failed to create live service"); goto err; @@ -1167,7 +1169,7 @@ int tv_resume(void) goto err; } - return 1; + return 0; err: tv_destroy(); -- 2.7.4 From 54a3b67d7271ec9034670a7e73d0d4c4b0b634cc Mon Sep 17 00:00:00 2001 From: "jinwoo.shin" Date: Wed, 12 Aug 2015 14:31:56 +0900 Subject: [PATCH 15/16] Add timer call for live service pause Change-Id: I98902148dcb481e7ec29909224db65969e8c0a96 Signed-off-by: jinwoo.shin --- src/main.c | 44 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 5 deletions(-) diff --git a/src/main.c b/src/main.c index 6616c90..e7c444b 100644 --- a/src/main.c +++ b/src/main.c @@ -28,6 +28,7 @@ #include "view.h" #define KEY_MAX 256 +#define PAUSE_WAIT_TIME 0.5 SET_TAG(PACKAGE) @@ -38,6 +39,7 @@ struct _appdata { Ecore_Event_Handler *key_up; tzsh_h tzsh; tzsh_tvsrv_h ta; + Ecore_Timer *pause_timer; int is_signal; int is_channel; @@ -201,13 +203,39 @@ static void _tv_signal_cb(void *data, int is_signal) } } -static void _pause(void *data) +Eina_Bool _tv_pause(void *data) { + struct _appdata *ad; int r; + if (!data) { + _ERR("failed to get data"); + return ECORE_CALLBACK_CANCEL; + } + + ad = data; + r = tv_pause(); if (r < 0) _ERR("Pause tv service failed"); + + ad->pause_timer = NULL; + + return ECORE_CALLBACK_CANCEL; +} + +static void _pause(void *data) +{ + struct _appdata *ad; + + if (!data) { + _ERR("failed to get data"); + return; + } + + ad = data; + + ad->pause_timer = ecore_timer_add(PAUSE_WAIT_TIME, _tv_pause, ad); } static void _resume(void *data) @@ -222,6 +250,11 @@ static void _resume(void *data) ad = data; + if (ad->pause_timer) { + ecore_timer_del(ad->pause_timer); + ad->pause_timer = NULL; + } + r = tv_resume(); if (r < 0) { _ERR("Resume tv service failed"); @@ -233,9 +266,6 @@ static void _resume(void *data) return; } } - - if (ad->win) - elm_win_activate(ad->win); } static bool _create(void *data) @@ -313,6 +343,11 @@ static void _terminate(void *data) ad = data; + if (ad->pause_timer) { + ecore_timer_del(ad->pause_timer); + ad->pause_timer = NULL; + } + if (ad->win) { tv_destroy(); @@ -369,7 +404,6 @@ static void _control(app_control_h control, void *data) viewmgr_update_view(VIEW_ERROR, UPDATE_TYPE_NOCHANNEL, NULL); } else { ad->is_channel = true; - viewmgr_show_view(VIEW_CHANNELINFO); } } -- 2.7.4 From 94978098d7df5e96124991057db50350199def3c Mon Sep 17 00:00:00 2001 From: "jinwoo.shin" Date: Tue, 18 Aug 2015 14:28:33 +0900 Subject: [PATCH 16/16] Add action menu view Change-Id: I2003259bdb25f2d3b3dc7e333f4bbeab59c9c0ab Signed-off-by: jinwoo.shin --- CMakeLists.txt | 1 + data/live-tv-theme.edc | 1 + data/live-tv.edc | 1 + data/view/action_menu.edc | 211 ++++++++ data/widget/button.edc | 972 +++++++++++++++++++++++++++++++++++ include/define.h | 28 + include/strings.h | 4 + include/util.h | 2 + include/view.h | 1 + res/images/btn_menu_favorite_dis.png | Bin 0 -> 1780 bytes res/images/btn_menu_favorite_foc.png | Bin 0 -> 1793 bytes res/images/btn_menu_favorite_nor.png | Bin 0 -> 1871 bytes res/images/btn_menu_favorite_sel.png | Bin 0 -> 1893 bytes res/images/btn_menu_lock_dis.png | Bin 0 -> 1369 bytes res/images/btn_menu_lock_foc.png | Bin 0 -> 1379 bytes res/images/btn_menu_lock_nor.png | Bin 0 -> 1430 bytes res/images/btn_menu_lock_sel.png | Bin 0 -> 1433 bytes res/images/btn_menu_unlock_dis.png | Bin 0 -> 1441 bytes res/images/btn_menu_unlock_foc.png | Bin 0 -> 1390 bytes res/images/btn_menu_unlock_nor.png | Bin 0 -> 1445 bytes res/images/btn_menu_unlock_sel.png | Bin 0 -> 1444 bytes src/main.c | 2 + src/tv.c | 24 - src/util.c | 28 + src/view_action_menu.c | 308 +++++++++++ 25 files changed, 1559 insertions(+), 24 deletions(-) create mode 100644 data/view/action_menu.edc create mode 100644 data/widget/button.edc create mode 100644 res/images/btn_menu_favorite_dis.png create mode 100644 res/images/btn_menu_favorite_foc.png create mode 100644 res/images/btn_menu_favorite_nor.png create mode 100644 res/images/btn_menu_favorite_sel.png create mode 100644 res/images/btn_menu_lock_dis.png create mode 100644 res/images/btn_menu_lock_foc.png create mode 100644 res/images/btn_menu_lock_nor.png create mode 100644 res/images/btn_menu_lock_sel.png create mode 100644 res/images/btn_menu_unlock_dis.png create mode 100644 res/images/btn_menu_unlock_foc.png create mode 100644 res/images/btn_menu_unlock_nor.png create mode 100644 res/images/btn_menu_unlock_sel.png create mode 100644 src/view_action_menu.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 2bd285b..729813b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -45,6 +45,7 @@ SET(SRCS src/main.c src/layout_channelinfo_search.c src/view_channelnumber.c src/view_error.c + src/view_action_menu.c src/util.c) SET(TARGET_EDJ "${PROJECT_NAME}.edj") diff --git a/data/live-tv-theme.edc b/data/live-tv-theme.edc index 52e787d..f5c808a 100644 --- a/data/live-tv-theme.edc +++ b/data/live-tv-theme.edc @@ -17,4 +17,5 @@ #include "../include/define.h" collections { + #include "widget/button.edc" } diff --git a/data/live-tv.edc b/data/live-tv.edc index 2c43574..b5043e0 100644 --- a/data/live-tv.edc +++ b/data/live-tv.edc @@ -20,4 +20,5 @@ collections { #include "view/channelinfo.edc" #include "view/channelnumber.edc" #include "view/error.edc" + #include "view/action_menu.edc" } diff --git a/data/view/action_menu.edc b/data/view/action_menu.edc new file mode 100644 index 0000000..973423d --- /dev/null +++ b/data/view/action_menu.edc @@ -0,0 +1,211 @@ +/* + * 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. + */ + +group { + name, GRP_VIEW_ACTION_MENU; + parts { + part { + name, "bg"; + type, RECT; + scale, 1; + description { + state, "default" 0.0; + color, 0 0 0 150; + } + } + part { + name, "menu_area"; + type, RECT; + scale, 1; + description { + state, "default" 0.0; + color, 255 255 255 255; + rel1.relative, 1.0 0.0; + min, 500 0; + align, 1.0 0.0; + fixed, 1 1; + } + } + + part { + name, "view.divider"; + type, RECT; + scale, 1; + description { + state, "default" 0.0; + color, 0 0 0 25; + rel1.to, "menu_area"; + rel2 { + to, "menu_area"; + relative, 0.0 1.0; + } + min, 1 0; + align, 1.0 0.5; + fixed, 1 0; + } + } + + part { + name, "padding.livetv.btn"; + type, SPACER; + scale, 1; + description { + state, "default" 0.0; + rel1.to, "menu_area"; + rel2 { + to, "menu_area"; + relative, 1.0 0.0; + } + min, 0 118; + align, 0.5 0.0; + fixed, 0 1; + } + } + + part { + name, PART_TOP_BUTTON; + type, SWALLOW; + scale, 1; + description { + state, "default" 0.0; + rel1 { + to, "padding.livetv.btn"; + relative, 0.5 0.5; + } + rel2 { + to, "padding.livetv.btn"; + relative, 0.5 0.5; + } + min, 327 64; + align, 0.5 0.5; + fixed, 1 1; + } + } + + part { + name, "padding.menu.divider.up"; + type, RECT; + scale, 1; + description { + state, "default" 0.0; + color, 224 224 224 255; + rel1 { + to, "padding.livetv.btn"; + relative, 0.0 1.0; + } + rel2.to, "padding.livetv.btn"; + min, 0 1; + align, 0.5 1.0; + fixed, 0 1; + } + } + + part { + name, "part.menu.bg"; + type, RECT; + scale, 1; + description { + state, "default" 0.0; + rel1 { + to, PART_MENU; + relative, 0.0 0.0; + } + rel2 { + to, PART_MENU; + relative, 1.0 1.0; + } + align, 0.0 0.0; + fixed, 1 1; + color, 224 224 224 255; + } + } + + part { + name, PART_MENU; + type, SWALLOW; + scale, 1; + description { + state, "default" 0.0; + rel1 { + to, "padding.menu.divider.up"; + relative, 0.0 1.0; + } + rel2 { + to, "padding.menu.divider.up"; + relative, 0.0 1.0; + } + min, 500 0; + align, 0.0 0.0; + fixed, 1 1; + } + } + + part { + name, "padding.menu.divider.down"; + type, RECT; + scale, 1; + description { + state, "default" 0.0; + color, 224 224 224 255; + rel1 { + to, PART_MENU; + relative, 0.0 1.0; + } + rel2 { + to, PART_MENU; + relative, 0.0 1.0; + } + min, 500 1; + align, 0.0 0.0; + fixed, 1 1; + } + } + + part { + name, "padding.channelinfo"; + type, SPACER; + scale, 1; + description { + state, "default" 0.0; + rel1.relative, 0.0 0.0; + rel2.relative, 0.0 0.0; + min, 40 40; + align, 0.0 0.0; + fixed, 1 1; + } + } + + part { + name, PART_CHANNELINFO; + type, SWALLOW; + scale, 1; + description { + state, "default" 0.0; + rel1 { + to, "padding.channelinfo"; + relative, 1.0 1.0; + } + rel2 { + to, "padding.channelinfo"; + relative, 1.0 1.0; + } + min, 536 174; + align, 0.0 0.0; + fixed, 1 1; + } + } + } +} diff --git a/data/widget/button.edc b/data/widget/button.edc new file mode 100644 index 0000000..ff68e9f --- /dev/null +++ b/data/widget/button.edc @@ -0,0 +1,972 @@ +/* + * 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. + */ + +#define STATE_NORMAL 0 +#define STATE_SELECTED 1 + +group { + name, "elm/button/base/style.livetv.button"; + data.item, "focus_highlight" "on"; + parts { + part { + name, "part.bg"; + type, RECT; + scale, 1; + description { + state, "default" 0.0; + min, 0 64; + } + } + + part { + name, "padding.text.left"; + type, SPACER; + scale, 1; + description { + state, "default" 0.0; + min, 20 0; + rel1.to, "part.bg"; + rel2 { + to, "part.bg"; + relative, 0.0 1.0; + } + align, 0.0 0.5; + fixed, 1 0; + } + } + + part { + name, "padding.text.right"; + type, SPACER; + scale, 1; + description { + state, "default" 0.0; + min, 20 0; + rel1 { + to, "part.bg"; + relative, 1.0 0.0; + } + rel2.to, "part.bg"; + align, 1.0 0.5; + fixed, 1 0; + } + } + + part { + name, "elm.text"; + type, TEXT; + scale, 1; + description { + state, "default" 0.0; + color, 87 87 87 255; + rel1 { + to, "padding.text.left"; + relative, 1.0 0.0; + } + rel2 { + to, "padding.text.right"; + relative, 0.0 1.0; + } + text { + font, FONT_LIGHT; + size, 28; + align, 0.5 0.5; + } + } + } + + part { + name, "part.inside.line.up"; + type, RECT; + scale, 1; + description { + state, "default" 0.0; + color, 194 194 194 255; + rel1.to, "part.bg"; + rel2 { + to, "part.bg"; + relative, 1.0 0.0; + } + min, 0 1; + align, 0.5 0.0; + fixed, 0 1; + } + } + + part { + name, "part.inside.line.left"; + type, RECT; + scale, 1; + description { + state, "default" 0.0; + color, 194 194 194 255; + rel1 { + to, "part.inside.line.up"; + relative, 0.0 1.0; + } + rel2 { + to, "part.bg"; + relative, 0.0 1.0; + } + min, 1 0; + align, 0.0 0.5; + fixed, 1 0; + } + } + + part { + name, "part.inside.line.down"; + type, RECT; + scale, 1; + description { + state, "default" 0.0; + color, 194 194 194 255; + rel1 { + to, "part.inside.line.left"; + relative, 1.0 1.0; + } + rel2.to, "part.bg"; + min, 0 1; + align, 0.5 1.0; + fixed, 0 1; + } + } + + part { + name, "part.inside.line.right"; + type, RECT; + scale, 1; + description { + state, "default" 0.0; + color, 194 194 194 255; + rel1 { + to, "part.inside.line.up"; + relative, 1.0 1.0; + } + rel2 { + to, "part.inside.line.down"; + relative, 1.0 0.0; + } + min, 1 0; + align, 1.0 0.5; + fixed, 1 0; + } + } + } +} + +#define DEFAULT 1 +#define SELECTED 2 +#define FOCUSED 3 +#define DISABLED 4 + +group { + name, "elm/button/base/style.action.menu.button"; + data.item, "focus_highlight" "on"; + script { + public is_toggle, is_selected, is_enabled, is_focused, is_init, cur_state; + + public init_values() { + if(get_int(is_init)==0) + { + set_int(is_toggle, 0); + set_int(is_enabled, 1); + set_int(is_focused, 1); + set_int(is_init, 1); + set_int(cur_state, -1); + } + } + public set_states() { + new togg; + new enab; + new foc; + new sel; + new c_state; + togg = get_int(is_toggle); + enab = get_int(is_enabled); + foc = get_int(is_focused); + sel = get_int(is_selected); + c_state = get_int(cur_state); + if(enab == 0) + { + if(c_state == DISABLED) + { + if (togg == 0) + { + run_program(PROGRAM:"do_disable"); + run_program(PROGRAM:"do_hide.1"); + } + else { + run_program(PROGRAM:"do_disable.1"); + run_program(PROGRAM:"do_hide"); + } + } + } + else + { + if(foc == 1) + { + if(c_state == FOCUSED) + { + if (togg == 0) + { + run_program(PROGRAM:"do_focus"); + run_program(PROGRAM:"do_hide.1"); + } + else { + run_program(PROGRAM:"do_focus.1"); + run_program(PROGRAM:"do_hide"); + } + } + } + else if(sel == 1) + { + if(c_state == SELECTED) + { + if (togg == 0) + { + run_program(PROGRAM:"do_select"); + run_program(PROGRAM:"do_hide.1"); + } + else { + run_program(PROGRAM:"do_select.1"); + run_program(PROGRAM:"do_hide"); + } + } + } + else + { + if(c_state == DEFAULT) + { + if (togg == 0) + { + run_program(PROGRAM:"do_default"); + run_program(PROGRAM:"do_hide.1"); + } + else { + run_program(PROGRAM:"do_default.1"); + run_program(PROGRAM:"do_hide"); + } + } + } + } + } + } + parts { + part { + name, "part.bg"; + type, RECT; + scale, 1; + description { + state, "default" 0.0; + min, 124 124; + color, 255 255 255 255; + } + description { + state, "focused" 0.0; + inherit, "default" 0.0; + color, 0 119 246 255; + } + } + + part { + name, "padding.icon1"; + type, SPACER; + scale, 1; + description { + state, "default" 0.0; + rel1.to, "part.bg"; + rel2 { + to, "part.bg"; + relative, 1.0 0.0; + } + min, 0 14; + align, 0.5 0.0; + fixed, 0 1; + } + } + + part { + name, "padding.icon2"; + type, SPACER; + scale, 1; + description { + state, "default" 0.0; + rel1 { + to, "part.bg"; + relative, 0.0 1.0; + } + rel2.to, "part.bg"; + min, 0 50; + align, 0.5 1.0; + fixed, 0 1; + } + } + + part { + name, "part.icon.bg"; + type, RECT; + scale, 1; + description { + state, "default" 0.0; + rel1 { + to, "padding.icon1"; + relative, 0.0 1.0; + } + rel2 { + to, "padding.icon2"; + relative, 1.0 0.0; + } + align, 0.5 0.5; + min, 60 60; + } + } + + part { + name, "elm.swallow.icon"; + type, SWALLOW; + scale, 1; + clip_to: "part.icon.bg"; + description { + state, "default" 0.0; + aspect, 1.0 1.0; + aspect_preference, BOTH; + rel1 { + to, "part.icon.bg"; + relative, 0.5 0.5; + } + rel2 { + to, "part.icon.bg"; + relative, 0.5 0.5; + } + align, 0.5 0.5; + fixed, 1 1; + min, 60 60; + } + description { + state, "focused" 0.0; + inherit, "default" 0.0; + visible, 0; + } + description { + state, "selected" 0.0; + inherit, "default" 0.0; + visible, 0; + } + description { + state, "disabled" 0.0; + inherit, "default" 0.0; + visible, 0; + } + description { + state, "invisible" 0.0; + inherit, "default" 0.0; + visible, 0; + } + } + part { + name, "elm.swallow.icon.focus"; + type, SWALLOW; + scale, 1; + clip_to: "part.icon.bg"; + description { + state, "default" 0.0; + aspect: 1.0 1.0; + aspect_preference: BOTH; + rel1 { + to, "part.icon.bg"; + relative, 0.5 0.5; + } + rel2 { + to, "part.icon.bg"; + relative, 0.5 0.5; + } + align, 0.5 0.5; + fixed, 1 1; + min, 60 60; + visible, 0; + } + description { + state, "focused" 0.0; + inherit, "default" 0.0; + visible, 1; + } + description { + state, "selected" 0.0; + inherit, "default" 0.0; + visible, 0; + } + description { + state, "disabled" 0.0; + inherit, "default" 0.0; + visible, 0; + } + description { + state, "invisible" 0.0; + inherit, "default" 0.0; + visible, 0; + } + } + part { + name, "elm.swallow.icon.select"; + type, SWALLOW; + scale, 1; + clip_to: "part.icon.bg"; + description { + state, "default" 0.0; + aspect: 1.0 1.0; + aspect_preference: BOTH; + rel1 { + to, "part.icon.bg"; + relative, 0.5 0.5; + } + rel2 { + to, "part.icon.bg"; + relative, 0.5 0.5; + } + align, 0.5 0.5; + fixed, 1 1; + min, 60 60; + visible, 0; + } + description { + state, "focused" 0.0; + inherit, "default" 0.0; + visible, 0; + } + description { + state, "selected" 0.0; + inherit, "default" 0.0; + visible, 1; + } + description { + state, "disabled" 0.0; + inherit, "default" 0.0; + visible, 0; + } + description { + state, "invisible" 0.0; + inherit, "default" 0.0; + visible, 0; + } + } + part { + name, "elm.swallow.icon.disable"; + type, SWALLOW; + scale, 1; + clip_to: "part.icon.bg"; + description { + state, "default" 0.0; + aspect: 1.0 1.0; + aspect_preference: BOTH; + rel1 { + to, "part.icon.bg"; + relative, 0.5 0.5; + } + rel2 { + to, "part.icon.bg"; + relative, 0.5 0.5; + } + align, 0.5 0.5; + fixed, 1 1; + min, 60 60; + visible, 0; + } + description { + state, "focused" 0.0; + inherit, "default" 0.0; + visible, 0; + } + description { + state, "selected" 0.0; + inherit, "default" 0.0; + visible, 0; + } + description { + state, "disabled" 0.0; + inherit, "default" 0.0; + visible, 1; + } + description { + state, "invisible" 0.0; + inherit, "default" 0.0; + visible, 0; + } + } + + part { + name, "elm.swallow.icon.1"; + type, SWALLOW; + scale, 1; + clip_to: "part.icon.bg"; + description { + state, "default" 0.0; + aspect, 1.0 1.0; + aspect_preference, BOTH; + rel1 { + to, "part.icon.bg"; + relative, 0.5 0.5; + } + rel2 { + to, "part.icon.bg"; + relative, 0.5 0.5; + } + align, 0.5 0.5; + fixed, 1 1; + min, 60 60; + } + description { + state, "focused" 0.0; + inherit, "default" 0.0; + visible, 0; + } + description { + state, "selected" 0.0; + inherit, "default" 0.0; + visible, 0; + } + description { + state, "disabled" 0.0; + inherit, "default" 0.0; + visible, 0; + } + description { + state, "invisible" 0.0; + inherit, "default" 0.0; + visible, 0; + } + } + part { + name, "elm.swallow.icon.1.focus"; + type, SWALLOW; + scale, 1; + clip_to: "part.icon.bg"; + description { + state, "default" 0.0; + aspect: 1.0 1.0; + aspect_preference: BOTH; + rel1 { + to, "part.icon.bg"; + relative, 0.5 0.5; + } + rel2 { + to, "part.icon.bg"; + relative, 0.5 0.5; + } + align, 0.5 0.5; + fixed, 1 1; + min, 60 60; + visible, 0; + } + description { + state, "focused" 0.0; + inherit, "default" 0.0; + visible, 1; + } + description { + state, "selected" 0.0; + inherit, "default" 0.0; + visible, 0; + } + description { + state, "disabled" 0.0; + inherit, "default" 0.0; + visible, 0; + } + description { + state, "invisible" 0.0; + inherit, "default" 0.0; + visible, 0; + } + } + part { + name, "elm.swallow.icon.1.select"; + type, SWALLOW; + scale, 1; + clip_to: "part.icon.bg"; + description { + state, "default" 0.0; + aspect: 1.0 1.0; + aspect_preference: BOTH; + rel1 { + to, "part.icon.bg"; + relative, 0.5 0.5; + } + rel2 { + to, "part.icon.bg"; + relative, 0.5 0.5; + } + align, 0.5 0.5; + fixed, 1 1; + min, 60 60; + visible, 0; + } + description { + state, "focused" 0.0; + inherit, "default" 0.0; + visible, 0; + } + description { + state, "selected" 0.0; + inherit, "default" 0.0; + visible, 1; + } + description { + state, "disabled" 0.0; + inherit, "default" 0.0; + visible, 0; + } + description { + state, "invisible" 0.0; + inherit, "default" 0.0; + visible, 0; + } + } + part { + name, "elm.swallow.icon.1.disable"; + type, SWALLOW; + scale, 1; + clip_to: "part.icon.bg"; + description { + state, "default" 0.0; + aspect: 1.0 1.0; + aspect_preference: BOTH; + rel1 { + to, "part.icon.bg"; + relative, 0.5 0.5; + } + rel2 { + to, "part.icon.bg"; + relative, 0.5 0.5; + } + align, 0.5 0.5; + fixed, 1 1; + min, 60 60; + visible, 0; + } + description { + state, "focused" 0.0; + inherit, "default" 0.0; + visible, 0; + } + description { + state, "selected" 0.0; + inherit, "default" 0.0; + visible, 0; + } + description { + state, "disabled" 0.0; + inherit, "default" 0.0; + visible, 1; + } + description { + state, "invisible" 0.0; + inherit, "default" 0.0; + visible, 0; + } + } + + part { + name, "padding.text"; + type, SPACER; + scale, 1; + description { + state, "default" 0.0; + rel1 { + to, "part.bg"; + relative, 0.0 1.0; + } + rel2.to, "part.bg"; + min, 0 24; + align, 0.5 1.0; + fixed, 0 1; + } + } + + part { + name, "elm.text"; + type, TEXT; + scale, 1; + description { + state, "default" 0.0; + color, 104 104 104 255; + rel1.to, "padding.text"; + rel2 { + to, "padding.text"; + relative, 1.0 0.0; + } + min, 0 20; + align, 0.5 1.0; + fixed, 0 1; + text { + font, FONT_LIGHT; + size, 20; + align, 0.5 0.5; + } + } + description { + state, "focused" 0.0; + inherit, "default" 0.0; + color, 255 255 255 255; + } + description { + state, "selected" 0.0; + inherit, "default" 0.0; + color, 64 136 211 255; + } + description { + state: "disabled" 0.0; + inherit: "default" 0.0; + color: 104 104 104 128; + } + description { + state, "invisible" 0.0; + inherit, "default" 0.0; + visible, 0; + } + } + + part { + name, "elm.text.1"; + type, TEXT; + scale, 1; + description { + state, "default" 0.0; + color, 104 104 104 255; + rel1.to, "padding.text"; + rel2 { + to, "padding.text"; + relative, 1.0 0.0; + } + min, 0 20; + align, 0.5 1.0; + fixed, 0 1; + text { + font, FONT_LIGHT; + size, 20; + align, 0.5 0.5; + } + } + description { + state, "focused" 0.0; + inherit, "default" 0.0; + color, 255 255 255 255; + } + description { + state, "selected" 0.0; + inherit, "default" 0.0; + color, 64 136 211 255; + } + description { + state: "disabled" 0.0; + inherit: "default" 0.0; + color: 104 104 104 128; + } + description { + state, "invisible" 0.0; + inherit, "default" 0.0; + visible, 0; + } + } + } + programs { + program { + name: "go_toggle"; + signal: "elm,state,toggle"; + source: "elm"; + script { + init_values(); + set_int(is_toggle, 1); + set_states(); + } + } + program { + name: "go_untoggle"; + signal: "elm,state,untoggle"; + source: "elm"; + script { + init_values(); + set_int(is_toggle, 0); + set_states(); + } + } + program { + name: "go_focused"; + signal: "elm,state,focused"; + source: "elm"; + script { + init_values(); + set_int(is_focused, 1); + set_states(); + } + } + program { + name: "go_unfocused"; + signal: "elm,state,unfocused"; + source: "elm"; + script { + init_values(); + set_int(is_focused, 0); + set_states(); + } + } + program { + name: "go_active"; + signal: "elm,state,selected"; + source: "elm"; + script { + init_values(); + set_int(is_selected, 1); + set_states(); + } + } + program { + name: "go_passive"; + signal: "elm,state,unselected"; + source: "elm"; + script { + init_values(); + set_int(is_selected, 0); + set_states(); + } + } + program { + name: "go_disabled"; + signal: "elm,state,disabled"; + source: "elm"; + script { + init_values(); + set_int(is_enabled, 0); + set_states(); + } + } + program { + name: "go_enabled"; + signal: "elm,state,enabled"; + source: "elm"; + script { + init_values(); + set_int(is_enabled, 1); + set_states(); + } + } + program { + name: "do_hide"; + action: STATE_SET "invisible" 0.0; + target: "elm.text"; + target: "elm.swallow.icon"; + target: "elm.swallow.icon.focus"; + target: "elm.swallow.icon.select"; + target: "elm.swallow.icon.disable"; + } + program { + name: "do_default"; + action: STATE_SET "default" 0.0; + target: "part.bg"; + target: "elm.text"; + target: "elm.swallow.icon"; + target: "elm.swallow.icon.focus"; + target: "elm.swallow.icon.select"; + target: "elm.swallow.icon.disable"; + } + program { + name: "do_focus"; + action: STATE_SET "focused" 0.0; + target: "part.bg"; + target: "elm.text"; + target: "elm.swallow.icon"; + target: "elm.swallow.icon.focus"; + target: "elm.swallow.icon.select"; + target: "elm.swallow.icon.disable"; + } + + program { + name: "do_select"; + action: STATE_SET "selected" 0.0; + target: "part.bg"; + target: "elm.text"; + target: "elm.swallow.icon"; + target: "elm.swallow.icon.focus"; + target: "elm.swallow.icon.select"; + target: "elm.swallow.icon.disable"; + } + + program { + name: "do_disable"; + action: STATE_SET "disabled" 0.0; + target: "part.bg"; + target: "elm.text"; + target: "elm.swallow.icon"; + target: "elm.swallow.icon.focus"; + target: "elm.swallow.icon.select"; + target: "elm.swallow.icon.disable"; + } + + program { + name: "do_hide.1"; + action: STATE_SET "invisible" 0.0; + target: "elm.text.1"; + target: "elm.swallow.icon.1"; + target: "elm.swallow.icon.1.focus"; + target: "elm.swallow.icon.1.select"; + target: "elm.swallow.icon.1.disable"; + } + + program { + name: "do_default.1"; + action: STATE_SET "default" 0.0; + target: "part.bg"; + target: "elm.text.1"; + target: "elm.swallow.icon.1"; + target: "elm.swallow.icon.1.focus"; + target: "elm.swallow.icon.1.select"; + target: "elm.swallow.icon.1.disable"; + } + program { + name: "do_focus.1"; + action: STATE_SET "focused" 0.0; + target: "part.bg"; + target: "elm.text.1"; + target: "elm.swallow.icon.1"; + target: "elm.swallow.icon.1.focus"; + target: "elm.swallow.icon.1.select"; + target: "elm.swallow.icon.1.disable"; + } + + program { + name: "do_select.1"; + action: STATE_SET "selected" 0.0; + target: "part.bg"; + target: "elm.text.1"; + target: "elm.swallow.icon.1"; + target: "elm.swallow.icon.1.focus"; + target: "elm.swallow.icon.1.select"; + target: "elm.swallow.icon.1.disable"; + } + + program { + name: "do_disable.1"; + action: STATE_SET "disabled" 0.0; + target: "part.bg"; + target: "elm.text.1"; + target: "elm.swallow.icon.1"; + target: "elm.swallow.icon.1.focus"; + target: "elm.swallow.icon.1.select"; + target: "elm.swallow.icon.1.disable"; + } + } +} + diff --git a/include/define.h b/include/define.h index ed6f92c..d521b65 100644 --- a/include/define.h +++ b/include/define.h @@ -23,6 +23,15 @@ #define PART_CONTENT "elm.swallow.content" #define PART_TEXT "elm.text" +#define PART_ICON "elm.swallow.icon" +#define PART_ICON_FOCUSED "elm.swallow.icon.focus" +#define PART_ICON_SELECTED "elm.swallow.icon.select" +#define PART_ICON_DISABLED "elm.swallow.icon.disable" +#define PART_TEXT_1 "elm.text.1" +#define PART_ICON_1 "elm.swallow.icon.1" +#define PART_ICON_1_FOCUSED "elm.swallow.icon.1.focus" +#define PART_ICON_1_SELECTED "elm.swallow.icon.1.select" +#define PART_ICON_1_DISABLED "elm.swallow.icon.1.disable" #define SOURCE_PROGRAM "program" #define SOURCE_ELM "elm" @@ -48,6 +57,19 @@ #define COLOR_OPTION_TEXT_FOCUSED 255 255 255 255 #define COLOR_OPTION_BORDER 154 154 154 255 +#define IMAGE_FAV_NOR IMAGEDIR"/btn_menu_favorite_nor.png" +#define IMAGE_FAV_FOC IMAGEDIR"/btn_menu_favorite_foc.png" +#define IMAGE_FAV_SEL IMAGEDIR"/btn_menu_favorite_sel.png" +#define IMAGE_FAV_DIS IMAGEDIR"/btn_menu_favorite_dis.png" +#define IMAGE_LOCK_NOR IMAGEDIR"/btn_menu_lock_nor.png" +#define IMAGE_LOCK_FOC IMAGEDIR"/btn_menu_lock_foc.png" +#define IMAGE_LOCK_SEL IMAGEDIR"/btn_menu_lock_sel.png" +#define IMAGE_LOCK_DIS IMAGEDIR"/btn_menu_lock_dis.png" +#define IMAGE_UNLOCK_NOR IMAGEDIR"/btn_menu_unlock_nor.png" +#define IMAGE_UNLOCK_FOC IMAGEDIR"/btn_menu_unlock_foc.png" +#define IMAGE_UNLOCK_SEL IMAGEDIR"/btn_menu_unlock_sel.png" +#define IMAGE_UNLOCK_DIS IMAGEDIR"/btn_menu_unlock_dis.png" + #define VIEW_CHANNELINFO "VIEW_CHANNELINFO" #define LAYOUT_CHANNELINFO "LAYOUT_CHANNELINFO" #define LAYOUT_CHANNELINFO_LIST "LAYOUT_CHANNELINFO_LIST" @@ -80,4 +102,10 @@ #define PART_ERROR_TITLE "part.error.title" #define PART_ERROR_TEXT "part.error.text" +#define VIEW_ACTION_MENU "VIEW_ACTION_MENU" +#define GRP_VIEW_ACTION_MENU "grp.view.action_menu" +#define PART_TOP_BUTTON "part.top.button" +#define PART_MENU "part.menu" +#define PART_CHANNELINFO "part.channelinfo" + #endif /* __LIVETV_DEFINE_H__*/ diff --git a/include/strings.h b/include/strings.h index 486c0bd..9722632 100644 --- a/include/strings.h +++ b/include/strings.h @@ -24,5 +24,9 @@ #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" +#define STR_LIVETV "Live TV" +#define STR_BUTTON_FAVORITE "Favorite" +#define STR_BUTTON_LOCK "Lock" +#define STR_BUTTON_UNLOCK "Unlock" #endif /* __AIR_LIVETV_STRINGS_H__*/ diff --git a/include/util.h b/include/util.h index 25afbc3..045d39e 100644 --- a/include/util.h +++ b/include/util.h @@ -24,5 +24,7 @@ Evas_Object *util_add_box(Evas_Object *parent, bool horizon); Evas_Object *util_add_scroller(Evas_Object *parent, const char *part); Evas_Object *util_add_icon(Evas_Object *parent, const char *file, const char *part); +Evas_Object *util_add_button(Evas_Object *parent, const char *part, + const char *text, const char *style); #endif diff --git a/include/view.h b/include/view.h index 8e0fc8e..5fbf8d4 100644 --- a/include/view.h +++ b/include/view.h @@ -32,5 +32,6 @@ void draw_channel_info(Evas_Object *obj, const struct tv_channel_info *channel_i view_class *view_channelnumber_get_vclass(void); view_class *view_channelinfo_get_vclass(void); view_class *view_error_get_vclass(void); +view_class *view_action_menu_get_vclass(void); #endif /* __LIVETV_VIEW_H__*/ diff --git a/res/images/btn_menu_favorite_dis.png b/res/images/btn_menu_favorite_dis.png new file mode 100644 index 0000000000000000000000000000000000000000..bd9bdd8fea7e302ea267636be304fe737619dd1b GIT binary patch literal 1780 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 G<^2oaAiI$O literal 0 HcmV?d00001 diff --git a/res/images/btn_menu_favorite_nor.png b/res/images/btn_menu_favorite_nor.png new file mode 100644 index 0000000000000000000000000000000000000000..a4729764761d5ea8f81b2abcbd37ccd1c4a469cf GIT binary patch literal 1871 zcmb7Fc~BEq7)MbM70L*xDB=>4A~wh7P9R{&5)GFa5KyoXk|kLo*|=Fq@Is>uQ0r~E zuMun&kWm>0l&YDEf=95P2q-8jwq8^^RK$+mD5!rp&U9yYzxUpJzu$My%Z&(MY(II{ zWGgExd&v?=N=QG;H_3+h^WWaV2;qtc#p01@GOm|lu$54OCc%J2EmOi$Sfu4k@7LN@J<;zhuMP|{V7}QznVB$1;vz9kjLX$IOudTp+VMVXmFW>L=h>Y8f023NTE^HYD--2wRN}@{^Z6NwRKS$T9_(@ zb!ZwUC+d+rZwyT2?(2puii9`(r5HjKMV1Po@-#K9!6lG@1d4eOn<-?`KoLhIf;e;$ zk0BOuKw1!sOJlKwW7y9z1RF(xDEM4RNar$m5S_;2fM5_yNMqA@LCio#5QhuVn1N$h ziAIOZG;-Kt&w@ohVMSlX@MN`KrAE82VRHs699hKp=#iLUiruu>~q8rTg+h4SsXeMDhLW8Iu~Lyf`m*KJrLrGNuyZB|H&1V zaDr-ShR>Q~?1<<%%kpEZ6Pu620&9o~!H7|?YkTsJn6RA^NEl`4d{(p~HFTNVd8N3L z?BfUcC2m}GWNx$VQxoc_ zt?zX^;&@|AOhqo|>~Uj@Ss=8Zd;8k8%5I;IBZF!F{vmNAcfC7~)aSfy>A$y0e5(KG zDr5gMR|f9P=WJ6_m%hT|K}MHao!uKBp_-Dt zto-TliJ|!er?*wi+3Hl)Xze>2zWjVwR!XMrqu_?@+Ixu(S>=f#lB(*y=F_&_Ap=Ds z)3ke6?W-qdTGgBdX>)7G&2Z))_P99Nz2+8uXUMJvlACUIrGzCgKXbuWJP1JX{uPf3jGu+?8~+&$J4#O|dm82L8?*y5Anp3@*riRJ*!xe|nQk z_k%oXYP0KGZScUs$EpVH8sC=auT=z( zJb9=ZzQDXtJA}9{ry5EqD^`jhu~a8sXYdB!6jsmKx7u{~4)rOwGdfs$mld(k!8n7q z;pX{_a*p}wFDA#K_{CEkX#aNSc;Isk4%06*nt7ckTicB5wDk#Hn@dM9kD7;@H|6ln zh~tX#j-t2W)8m);-fn3%F-+pCbDvq)m^OGFRDJ8QWqH@i1BtHNqmxrAAKJLV4w}Av zs?xp3ys`L7`&QB`gP^BhzrWY7bNI(Lv)Cbzx6Udwch8pM!Yak?&X)CM<-u_y&Yisc zg!sB9`|iihWfM=FYc(YlwB#Fi_l}E|9ZNfXk$iCJ(bBj(qJOYuKD~YB8(Z2Ky(nh6vEDhpZ+1-A#$M^P-SlHstF}+v_QdVNq`Z@R_xF_!g`c~z^^=|0-{wIui_e*G1t|6fH2vrmn zm5$&=RlF5wtTe@1&oeYH!A8Mjx*ia-S53O-|zR`^OnY{#{2ag z*ptO#`6(x$YDPx7KW{JQkGyI$F=7BM*U<4~DxIx0VJwNBOu+!9L7RrDF|9r)>m}dlLJ%Mjgh8YE0s#~Xz+4Chxy&ozK%)`90D;4S4-cEMX40o3YE<#T z7PAwx(`nj>fM9lZc33tqj5MWzkVqtQbHFf%(cn-y1g*7j2r9Uf0mUet2{+O>NdRs} zZ3;P?7PA>o--lo@#>9LiCa4dIVp0ZLv_=pL+0uADFA^7)cZ?B^JUEliK=5x$hi;|XL^n9El{ken~!hjSIEg4w|mg-DKeVwD6% zYY83Zw&%v;pRkgzViB1M)6%3Vfh03KD<7Lq(j=8m8Ub0n02q;k6M8b63UQa^eUvC> z!p)doVImE{ySyU!7wijps6fHv!TfNT2^E4QC@e$;Jh@~vAC{s*1^WY5|9^4?GERW* zX85c*I**u+b1y%(I016akDClnF-sjL?sE9ru*xsPUsic|9G|`x?*|m zu3h;jtd+$90qu$B#Wf3StkZ{%wEEsjT?F=--fv`?_cE))HgVL{vi$PXp?9~;QLKy` z)_j!cFE{UdoBwu&q~UU@IHIui#f{^_O3M6(dgGdVU9`1k%NFP5)$IDqPN`3W^|xe> z#w~8xeI`};O+2%=u&wA;a^DkP0q5tC`ocI80#5w~-Ca7u3`I3*F+|9Ror)N~JJmdj3De|0q? z7H=2YqaF`lg$^1dtIuB;r|KJOf8D$6oUNrH(OcCG_sTkEISW0Yif-J#pIOx&n>e$u z_kCWQewXc1!^4Kmizy2M|6~5C*81-b?_`zxJj)TSCCaW2xiKuT_vAfE(T5zN$jyH7 zQN!Xc9dXTZ+LO1o6lgqp+46Z=;H^`h@h!%| zs=TazwSDIP&UBiwYbYzp8MVak&&&(bR?xWC_v!W$XE4{v-bXp(>w_E1&v>jBeDfsK z?|eJZeXL4%($f7tt2AZp@s$heHa<8`^>to~hA!eg%0?YnQWE*c20U$Z%08HWNG&db zBKky<`y+kN&opYJ+k)nGEgreY-)^m$rY=|!p0~*y5?OGi8Q$UJoV)|(L9A&WIg2Yc z-!qq2&B&VeNKc&RHx@4cD+Kn~AN5l2y72TD?eZ5f_MwOFdYx^G=5P)@4NO>fa7M?$ zc}Hh?Zl7Wdzg?&9u&;aWO)O~Z04zcO4onSsUV9|t?`Kppm#VDre5rZe(kqzeSb795 z!d+}bDUs&9df*C(AFKaCxH`Zn8;5@D;-(MWv~K-DbKpirM9JdadDxknE^Qt!9U~vF z3P{*hx=OOgP@%T9Df}|-C7q>&HPPpUN6nSmURUdsA!}R}OL>cPr`cB*G`2<=Dx|jjWlxZfdQDR6)Hl9OaFOLq zZe%_leU002L1OQ-(Q&l;AiO&j3{Xs7>7vr)K`Hak$=4*Wvwf|+?i2t3 literal 0 HcmV?d00001 diff --git a/res/images/btn_menu_lock_dis.png b/res/images/btn_menu_lock_dis.png new file mode 100644 index 0000000000000000000000000000000000000000..d5827a0b69c26a88ea0654b08c0a05a747556791 GIT binary patch literal 1369 zcmeAS@N?(olHy`uVBq!ia0vp^HXzKw1|+Ti+$;i8k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ-L~|l`=yjN+NuHtdjF{^%6m9^eS=-fVzQ(*;f=KCTFLXC?ut( zXXe=|z2CiGNg*@ERw>-n*TA>HIW;5GqpB!1xXLdixhgx^GDXSWPQj+a3TQxXYDuC( zMQ%=Bu~mhw64+cTAR8pCucQE0Qj%?}1aVY^Z-9bxeo?A|sh+WJvVozYf|;3~p^2%P znW2t?k%6I+z5x)K=^C0?nVMM{nJYkn6417ylr*a#7dNO~K%T8qMoCG5mA-y?dAVM> zv0i>ry1t>Mr6tG=BO_g)3fZ zE`@j@w*YQzUNJP7fB~jokyxN_sAmB35=^15FMg%Dxp39RB|)hO_hL1;IHa;5RX-@T zIKQ+g85nVC${?!>telHd6HD@oLh|!-V4)b0kzbNuoRMFk;2dnGpb?&#my%yztO-`{ z>ucqiS6q^qmz?V9Vygr+K`%2i#mdCY($UP>!obMD%+S!#)zs0z(#6%p(ACM*(A?F` z(h{cEB|o_|H#M&WrZ)wl*AS;(P*TV(0NU)5T9jFqn&MWJpQ`}&vQ;Kdx0t))G!Lpb z1*cog-EivF2RcR{6tPGV4HE*U9uO0rY=Inj!cWZuruHIWvR18*xz51Ac-GU!F{I+w zn^}9k4hKlI1xH_5dh}r4zs3@QCC!Vk%wO20x0hLeLHWbjFMM-y#o6bE$hgMnT(h@& zv7p)BIW+6BbWLl}tVJptEuZ~;ps0BA=c!`9pGD^s4R3E-t8uhJbmN2#Evh<+oZb+we#`iDGkcrwOqD%nCTi~%Rhpg=_{+Lo@Q||tw_n7PI%)r$*{SO;aQAOE z3$cB&!svJl=b=ow_cl*icFU@_nA8abGU*94$4H2*)<{ec#RtbhV Wyg`A2ckiA86?UGkelF{r5}E*0)$@e_ literal 0 HcmV?d00001 diff --git a/res/images/btn_menu_lock_foc.png b/res/images/btn_menu_lock_foc.png new file mode 100644 index 0000000000000000000000000000000000000000..5671cfc5bb6e8995cfc7d0876c47622a3c02e00d GIT binary patch literal 1379 zcmb7Ee@qi+7_JkPm8pOZHtn{{xy6x4??-!g^g?0RyH*+~BhXRe631~p=vmq;cL!}T zi^~St7R}6bM9hc@AjSoCERKz&2@;HMFkKum$fjFhZpIkcSR~9XlI%O6=pV*pm%ICZ zo(?CC<4%ctSA=Yg`lWGwPL*#w!?oW z&cl%8x5GZdgL)#Y7?6rv6tS|U%qz461)Co(DufDRG$06x8V|)n4Pljz+2JK#8qD== z1csJOw4fbc4yxKy4zaQ#LWJ3pC!iPxk)#>35+sT3gm4tY5fr>+9%iKplEx`$<$-}W z#a~BPaIO_!U}c8`niioEBpQvHqZYHQ)FYV9X45%vJP%mpsqwJJ$MVAJ_9O!*s)8a# zG)WFaIwM~zH)(blM7o?pDB|&~5{K0lp@3vajE^9g8AU=NJ+CEeRjUvmhVfWy)f`7}ngJ9mZTXjSaum+m zEH0M9P$!X(5(JaPK8gWsX20a8NruB*RtJlt1chNv!bWj~6D3)W!zi3_T9a6JSk?Hj zAnN{ftn?7;cp{c&6_M9u#VgAV$;y`pWKC8Bas*;4N$6Fd6!yzeHCHdoa+aK^NX??( zrN|*@Nmp8WjDO0-kuHk`Cny}GieU_g=X0dR$yf>8!R5Q)6|DdNXoY|v5WN{5X^!L; z=s114+Uj7jdRW9TI3Wr+3W0lNeFnpt9yiB$V?WJw6zxo5w!AOfPXFpCIs3!t8)GG$ z*Vr|*yK_&^$43IKRZP6yvG3W`td>u%?;Tvo+7G|n{D3^pF@u*2qUY}I8$J5-%ut+q z>vmmp6c$R&C+>Wgn!V*D+Ll|&8!J0Tj&1(_J!5`KbU5v6jhoedX#? zJEmNJc)ne1yqeNCxYBT8c%;(x2%i@(+?jh-ZoGuja6OQWqRlSrhnMO!4qeE zBhI;$kC^@IXUA_^q&KhK`E;Ut;OVUXXMUjrM{k>Zg9on7)o#ogwoINo^#wv03lGj& zKVU9&yV$*#@6VacqkoNcU+OjOcst|8cHu_%rTQD0FSV{WO>F%wp=~-nPR!NJ-^y&5 zT)2KQF`quTE@w=zq@Nt_pYpzqUYBx?D?u?w{ko_O+UB!Zr5UO zPe!Y6sME)06#hHi*=KEgfg370zpb$~w{&`{)e{)`yR53@(88Bvj+?XJjAx(v-84fj sW_@0h$Z>TX$WF?&tlad>#e`w4VN|*`oz+!vMZfmk&NA+-qvqZJ04uKVuK)l5 literal 0 HcmV?d00001 diff --git a/res/images/btn_menu_lock_nor.png b/res/images/btn_menu_lock_nor.png new file mode 100644 index 0000000000000000000000000000000000000000..5f384947ac2a948e1812ac674c945025a5b417e0 GIT binary patch literal 1430 zcmeAS@N?(olHy`uVBq!ia0vp^HXzKw1|+Ti+$;i8k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ-L~|!!ko6N+NuHtdjF{^%6m9^eS=-fVzQ(*;f=KCTFLXC?ut( zXXe=|z2CiGNg*@ERw>-n*TA>HIW;5GqpB!1xXLdixhgx^GDXSWPQj+a3TQxXYDuC( zMQ%=Bu~mhw64+cTAR8pCucQE0Qj%?}1aVY^Z-9bxeo?A|sh+WJvVozYf|;3~p^2%P znW2t?k%6I+z5x)K=^C0?nVMM{nJYkn6417ylr*a#7dNO~K%T8qMoCG5mA-y?dAVM> zv0i>ry1t>Mr6tG=BO_g)3fZ zE`@j@x4_pIZg5^PG@yV%reBd*pl_&Wpr4xy@)uZjaY;}r!Wmdq7l%|9r0NHy7U!21 zB?IFlO&O*c7&4a6BsFpIWGChrManjC7v#}N``KhE@mcU znp?P80L?Rm>GjMjE=kNwP6gQq(wm9UYl2s=m2**QVo82cNPd0}Ean3;@=NlIGx7@* zoP*62G{Q6UQu51-H9^q=@uf>@QD#|cid#{Bt^zn*tunFLZ|>$|=4NbcWNK~%^s1qu zql=M+i#&rDPg4#bc8-AF(4%lm=G|~)nPsTM94K-8JHhFrD(EiONa!= zBDRfpu5>uAkri-kkzIU)XGLI>qiX3t@%YKoCYF1xYtR4P|73dk-re7~?*D!-_FnbM zmll13%QFm;#6*@Ev}*b!a%qe7CaP`L(VirqdE2ZyqBOBwW$8h=3YNYP3ePVk_HVP7 zycC)wkkcfh(Ii};e%xA7*ag%R9(nF=5`PND v5P>+MEgX~U<)MKaJmU~JoZqPLW07Fs3{Kl-aORf}sHF6C^>bP0l+XkKU7hz@ literal 0 HcmV?d00001 diff --git a/res/images/btn_menu_lock_sel.png b/res/images/btn_menu_lock_sel.png new file mode 100644 index 0000000000000000000000000000000000000000..1baa790190a4eae0ad430bbfa92251e189e961f3 GIT binary patch literal 1433 zcmb7EeN5D57(d|z#>bSeF%2R0NDx%6?cMc03Wpr+9h?DV+)XjMg>o&>aMyNi*&Y00 z;xQP;X&gGoL;_JEm`p{6S%5IexrMl8xVcQcCB~7MFvBuGvP`zHvA2B9Ka9zmw(m!t z-|u;z-}Aih(TeiogxIaIDwQh1SwdEVF<<#&qQD7APlKt%3i-Bof`St;(}eOgMf(FS}1Km)Sf0fF)~Ffvrb)UljZ^Jr{B z1F^JKvmYx%$^?R`XG@wz#?@Tz_B1zmEVO2K0hAxW0fCQ^DJbCcauOb}YLG$87o4%!unu(CVWB z-bA_c&yH@#%dS2$GdR~ACml4X|&vG>HmvWS{tYk?t zBKs~wJ4D_GE$fQ2FYs^HlSYSLuft3_kSdDWNS&E9>g_fIrYj3XY!#rk1kIB-Hla1?G)b0aF%hOm>gxdT7_dUkA2q%EaQpY&Cz_i{({ z=4;>Y+06Ia3*#>52In)??ufSw4IR@3?X9iH`zxNbrFq|sS%^A+CJ4QbURjzyyv^tgYQ1cAlOe-PUz}2YsNTGnCSgwC0pju}cTuYsvcM;ONul?nESh z)OPCJ#D==+WN-T3;V%~7Ps~tR2DL-c)%(n+rN6GH<5%y?v+BE%vGGT;+gmK#v~y8? z(*+lk`(yK<2b2pAMQwZ#1v0vS8eo9_~IWnr0m3_9hRD)uzg@-SY;XNxbTg7_O%>1 z;(__&p|E;3D(BJPS(C$u`Gb5=XiSuTd^{#kR@gpguXSX-Q5qagnwTj*8IpV8`5Tcn zTMq?)NQ!%=x;Mh4-FX&%rSs`XVNE#GC+-mcqUN6kLj zG<6~&ly^T}`lw$>)Ew%c-*EzHs0BKlu+PSVh=n`W1~`3&#S<)hhL2riULGm{u-Jr@frKQdAxM7kgs-8vpKK(u6=&Z2DQO-tss`^P_x;raA24QSZJhbzs!U*eko;vf#xKy$OmLz z@IwkCQzBH!78pc2cLZO+;aDX0OY=ej$#fwmphLBY&gWCkHES)&PVQ+K&$X7^)d5cD zWtO`)g_H`7)i8$#)=Ml-1=tqWMYUy>QW zms9*HSpF#%eIb^hM2?XK(Jcs-3z^R?7i2*y7XlFFGC-*Xyq^_W_2a_=lI8sC~Bq6NV*ZjZ8(aWXfo4m!*GNqfdU8$&tuvDqm>Q>p;L2~%sdIt8??|;X*0w4Zo`3G?H8xs#(PhP40#e1ZC zL;vk7509Rtihr73bG&W1N1d9@#JF0A5<8IkCz>|W(2{eu_ZGXZc|3Yw$==#~qq{yz z{+3*t@peUH)cOx^MGt-LiC;Uo(iHXRHO;j#a(R*}=m|SI-)NQLZ+s*c@-IT6rWOB7dY~3!@xnq^~4)$SK+1 literal 0 HcmV?d00001 diff --git a/res/images/btn_menu_unlock_foc.png b/res/images/btn_menu_unlock_foc.png new file mode 100644 index 0000000000000000000000000000000000000000..8e354891076c2a5e5a61192c2a98a7eae3278f78 GIT binary patch literal 1390 zcmeAS@N?(olHy`uVBq!ia0vp^HXzKw1|+Ti+$;i8k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ-L~|!!ko6N+NuHtdjF{^%6m9^eS=-fVzQ(*;f=KCTFLXC?ut( zXXe=|z2CiGNg*@ERw>-n*TA>HIW;5GqpB!1xXLdixhgx^GDXSWPQj+a3TQxXYDuC( zMQ%=Bu~mhw64+cTAR8pCucQE0Qj%?}1aVY^Z-9bxeo?A|sh+WJvVozYf|;3~p^2%P znW2t?k%6I+z5x)K=^C0?nVMM{nJYkn6417ylr*a#7dNO~K%T8qMoCG5mA-y?dAVM> zv0i>ry1t>Mr6tG=BO_g)3fZ zE`@j@x4_pIZg5^PG@yV%reBd*pl_&Wpr4xy@)uZjaY;}r!Wmdq7l%|9r0NHy7U!21 zB?IFlO&O*c7&4a6BsFpIWGChrManjC7v#}N``KhE@mcGjMjE=kNwP6gQq(wm9U>x@^gm2**QVo82cNPd0}Ean3;@=NlIGx7@* zoP*62G{Q6UQu51-H9^q=@uf>@QD#|cid#{Bt^zn*tunFLZ)$F6=;UH)U~Fz=>S}6e zXyM}MX6b5VYT)7s3;_c}C8*vMQo>3f=m>pKVn9k9Fd<-y12N%A9ms)amef384k-d= zh0pA<-x(Mf*Lk`)hE&{oGsE8Fu!Bgu^x8>$U8@6RN?t#a5GWL2KNuOa^=^y|izuu3 z#n1~|CpUBP`E~7j@g&6ju1mlhtsmmtX8-!^4muv3WOMoTU%8qm3-qV|-tp}2(>(?} z!FsOVr#3DyXw~#dzdJuCe06l$7|KfgWk>E{8aYc1j$=H7ml-4 zu+B9*^MT>R!MYZ^Zw_ocS!?n@+)!KO_gq&R-?fql54sOMCm zf8;G+{TPE^>f2AxsD6GY?=4Eunia{&s&_Yx5y{2oF+Cm zleKC7mrYwHt(qIdcIwcxg1W7OX)|2A!9fNMJw2{^E&~RQbffKDEj~9vC7`FPpUXO@ GgeCyBCi40K literal 0 HcmV?d00001 diff --git a/res/images/btn_menu_unlock_nor.png b/res/images/btn_menu_unlock_nor.png new file mode 100644 index 0000000000000000000000000000000000000000..fb89ee97bf98afdcfd0f50642e0c4b1039ed605d GIT binary patch literal 1445 zcmeAS@N?(olHy`uVBq!ia0vp^HXzKw1|+Ti+$;i8k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ-L~|!!ko6N+NuHtdjF{^%6m9^eS=-fVzQ(*;f=KCTFLXC?ut( zXXe=|z2CiGNg*@ERw>-n*TA>HIW;5GqpB!1xXLdixhgx^GDXSWPQj+a3TQxXYDuC( zMQ%=Bu~mhw64+cTAR8pCucQE0Qj%?}1aVY^Z-9bxeo?A|sh+WJvVozYf|;3~p^2%P znW2t?k%6I+z5x)K=^C0?nVMM{nJYkn6417ylr*a#7dNO~K%T8qMoCG5mA-y?dAVM> zv0i>ry1t>Mr6tG=BO_g)3fZ zE`@j@x4_pIZg5^PG@yV%reBd*pl_&Wpr4xy@)uZjaY;}r!Wmdq7l%|9r0NHy7U!21 zB?IFlO&O*c7&4a6BsFpIWGChrManjC7v#}N``KhE@mc=x;TbZ+}_is!{J$lP;;>HjSpTfQB_mjky9Xn(DSnm7ZS1<4Vv`l|y`F!?e%lKsL zzT}^pTsrevTQz+Wxq@dL5?NMoPw7Eg`on^V)6;v7Ce2A)&%N5`70c`gaw~+rh3+)z zUU*x!?WyY0%P!gxY>pEc)E~GlS?$REf+^5|rO#JPj* z9`Ba|5iHUR#NPZ>$Ua&8YOB=--f0IGWFDHDz$(*d_hFjj?C=ZBeh0Ny7@k~Gc)v(=el2uA6r+8ImcINY->3+o#Ggy;1ExaIhQ%>W~jE5W*(|B8yH-()_ z-d@2d92c=g?VzZ|^*O!1MmsL<7t>=(Pl(yP;n&J5pKTz)F>CSJUwU6vp8UJdecZ8C z;Cr;!?K%O!wc)LQ6lx|so44AeHMZk`eC@iklFJNQYt`TU@cnU8d-ax8issFhXAiB~ z^Z6ZXVrWQrgx;0eMiMt9^*Q{x-CEAtcYs6M021go=Kc^$VE8gI&-MB=(F9Pz>FMg{ Jvd$@?2>|?)1`_}P literal 0 HcmV?d00001 diff --git a/res/images/btn_menu_unlock_sel.png b/res/images/btn_menu_unlock_sel.png new file mode 100644 index 0000000000000000000000000000000000000000..b41240aff9ae6a52f683111317ab995a3feb0037 GIT binary patch literal 1444 zcmeAS@N?(olHy`uVBq!ia0vp^HXzKw1|+Ti+$;i8k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ-L~|!!ko6N+NuHtdjF{^%6m9^eS=-fVzQ(*;f=KCTFLXC?ut( zXXe=|z2CiGNg*@ERw>-n*TA>HIW;5GqpB!1xXLdixhgx^GDXSWPQj+a3TQxXYDuC( zMQ%=Bu~mhw64+cTAR8pCucQE0Qj%?}1aVY^Z-9bxeo?A|sh+WJvVozYf|;3~p^2%P znW2t?k%6I+z5x)K=^C0?nVMM{nJYkn6417ylr*a#7dNO~K%T8qMoCG5mA-y?dAVM> zv0i>ry1t>Mr6tG=BO_g)3fZ zE`@j@x4_pIZg5^PG@yV%reBd*pl_&Wpr4xy@)uZjaY;}r!Wmdq7l%|9r0NHy7U!21 zB?IFlO&O*c7&4a6BsFpIWGChrManjC7v#}N``KhE@mc=c`5nj#hRdKf%wuTwJ5VJHN~wcKUV=9u2z{?>^C(xG<0&YG%z+dGIcdI zG_(ME#1iNl0~beN2pAYDLG`AP5?1;^N9cnR15)CE2?0|ahzU>XKn^^!q~-y0ND(kA zd|!B5je&vjiKmNWNX4x;vn;)t9VHxu0|Ns#h8{WQx8{hGzY7EuxeH3aU3&Mv#97?L(Q?lr**OQ;T=@Q)=HI+kQpqldH2V=E-e4sy>8V5~LZ4F0t%=zjM>vrEp)xPB+_g)I;>dwBfe z?8KbLUE%Dn4f?+<$UL-4T|B}4`=ihGq7&*Cy=bhBaM^WAJ+_JqUf(?QizrO8U%d`LN-W^@;9ENwAUy8{!7hCuh zJ~w&YKD+E;jYU&nyYQ5|!8dta_wG5Yq;m*}H2e5=TrAn)Xu*>@Ys2lfE!TMu#eWX9 zGv~;BQdFP%*yGX4FMc}0EulfW x4?Larojle&*RR5M%71UFMg{vd$@?2>`%=2%`W1 literal 0 HcmV?d00001 diff --git a/src/main.c b/src/main.c index e7c444b..16fc240 100644 --- a/src/main.c +++ b/src/main.c @@ -311,6 +311,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); + viewmgr_add_view(view_action_menu_get_vclass(), NULL); r = tv_create(); if (r < 0) { @@ -359,6 +360,7 @@ static void _terminate(void *data) viewmgr_remove_view(VIEW_CHANNELINFO); viewmgr_remove_view(VIEW_CHANNELNUMBER); viewmgr_remove_view(VIEW_ERROR); + viewmgr_remove_view(VIEW_ACTION_MENU); viewmgr_destroy(); evas_object_del(ad->win); diff --git a/src/tv.c b/src/tv.c index ecf5049..d5ba1fd 100644 --- a/src/tv.c +++ b/src/tv.c @@ -1023,30 +1023,6 @@ void tv_signal_cb_set(void (*cb)(void *data, int is_signal), void *data) } /** - * Sets window id for tv overlay. - * - * @param window_id The window id to overlay - * @return If the operation was sucessful 0 is returned; otherwise negative value is returned - */ -int tv_overlay_set(void *window_id) -{ - int r; - - if (!g_tv_info.live_svc) { - _ERR("failed to get live service"); - return -1; - } - - r = tv_service_live_set_window_overlay(g_tv_info.live_svc, window_id); - if (r < 0) { - _ERR("failed to set overlay"); - return -1; - } - - return 0; -} - -/** * Destory the tv service handles. * * @return If the operation was sucessful 0 is returned; otherwise negative value is returned diff --git a/src/util.c b/src/util.c index ba2acdd..b9b3f72 100644 --- a/src/util.c +++ b/src/util.c @@ -124,5 +124,33 @@ Evas_Object *util_add_icon(Evas_Object *parent, const char *file, evas_object_show(ic); return ic; +} + +Evas_Object *util_add_button(Evas_Object *parent, const char *part, + const char *text, const char *style) +{ + Evas_Object *btn; + + if (!parent) { + _ERR("Invalid argument."); + return NULL; + } + btn = elm_button_add(parent); + if (!btn) { + _ERR("elm_button_add failed."); + return NULL; + } + + if (part) + elm_object_part_content_set(parent, part, btn); + if (text) + elm_object_text_set(btn, text); + if (style) + elm_object_style_set(btn, style); + + evas_object_show(btn); + + return btn; } + diff --git a/src/view_action_menu.c b/src/view_action_menu.c new file mode 100644 index 0000000..97f6473 --- /dev/null +++ b/src/view_action_menu.c @@ -0,0 +1,308 @@ +/* + * 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 "util.h" + +#define BUTTON_MAX 16 +#define BUTTON_BORDER 1 +#define ITEMS_IN_ROW 4 + +#define STYLE_LIVETV_BTN "style.livetv.button" +#define STYLE_ACTION_MENU_BTN "style.action.menu.button" + +#define UNTOGGLE 0 +#define TOGGLE 1 + +enum _button_id { + BUTTON_INVALID = -1, + BUTTON_FAV, + BUTTON_LOCK, +}; + +struct _priv { + Evas_Object *base; + Evas_Object *menu_btn[BUTTON_MAX]; +}; + +struct _button_state { + const char *text; + const char *normal; + const char *focused; + const char *selected; + const char *disabled; +}; + +struct _button { + int id; + struct _button_state state[2]; +}; + +static struct _button buttons[] = { + { + .id = BUTTON_FAV, + .state[UNTOGGLE] = { + .text = STR_BUTTON_FAVORITE, + .normal = IMAGE_FAV_NOR, + .focused = IMAGE_FAV_FOC, + .selected = IMAGE_FAV_SEL, + .disabled = IMAGE_FAV_DIS + }, + .state[TOGGLE] = { + .text = STR_BUTTON_FAVORITE, + .normal = IMAGE_FAV_NOR, + .focused = IMAGE_FAV_FOC, + .selected = IMAGE_FAV_SEL, + .disabled = IMAGE_FAV_DIS + } + }, + { + .id = BUTTON_LOCK, + .state[UNTOGGLE] = { + .text = STR_BUTTON_LOCK, + .normal = IMAGE_LOCK_NOR, + .focused = IMAGE_LOCK_FOC, + .selected = IMAGE_LOCK_SEL, + .disabled = IMAGE_LOCK_DIS + }, + .state[TOGGLE] = { + .text = STR_BUTTON_UNLOCK, + .normal = IMAGE_UNLOCK_NOR, + .focused = IMAGE_UNLOCK_FOC, + .selected = IMAGE_UNLOCK_SEL, + .disabled = IMAGE_UNLOCK_DIS + } + }, + { + .id = BUTTON_INVALID + } +}; + +static bool _draw_top_area(struct _priv *priv) +{ + Evas_Object *btn; + + btn = util_add_button(priv->base, + PART_TOP_BUTTON, STR_LIVETV, STYLE_LIVETV_BTN); + if (!btn) { + _ERR("Add button failed."); + return false; + } + + return true; +} + +static bool _draw_menu_area(struct _priv *priv) +{ + Evas_Object *table, *btn; + int i, row, col; + + table = elm_table_add(priv->base); + if (!table) { + _ERR("Add table failed."); + return false; + } + elm_table_padding_set(table, BUTTON_BORDER, BUTTON_BORDER); + evas_object_show(table); + elm_object_part_content_set(priv->base, PART_MENU, table); + + i = 0; + while (buttons[i].id != BUTTON_INVALID && i < BUTTON_MAX) { + btn = util_add_button(priv->base, NULL, + buttons[i].state[UNTOGGLE].text, + STYLE_ACTION_MENU_BTN); + if (!btn) { + _ERR("Add button failed."); + evas_object_del(table); + return false; + } + + util_add_icon(btn, buttons[i].state[UNTOGGLE].normal, + PART_ICON); + util_add_icon(btn, buttons[i].state[UNTOGGLE].focused, + PART_ICON_FOCUSED); + util_add_icon(btn, buttons[i].state[UNTOGGLE].selected, + PART_ICON_SELECTED); + util_add_icon(btn, buttons[i].state[UNTOGGLE].disabled, + PART_ICON_DISABLED); + elm_object_part_text_set(btn, PART_TEXT_1, + buttons[i].state[TOGGLE].text); + util_add_icon(btn, buttons[i].state[TOGGLE].normal, + PART_ICON_1); + util_add_icon(btn, buttons[i].state[TOGGLE].focused, + PART_ICON_1_FOCUSED); + util_add_icon(btn, buttons[i].state[TOGGLE].selected, + PART_ICON_1_SELECTED); + util_add_icon(btn, buttons[i].state[TOGGLE].disabled, + PART_ICON_1_DISABLED); + + col = i % ITEMS_IN_ROW; + row = i / ITEMS_IN_ROW; + elm_table_pack(table, btn, col, row, 1, 1); + + priv->menu_btn[i] = btn; + + i++; + } + + while (col + 1 != ITEMS_IN_ROW) { + btn = util_add_button(priv->base, NULL, NULL, + STYLE_ACTION_MENU_BTN); + if (!btn) { + _ERR("Add button failed."); + evas_object_del(table); + return false; + } + + col = i % ITEMS_IN_ROW; + + elm_table_pack(table, btn, col, row, 1, 1); + + i++; + } + + elm_object_focus_next_object_set(priv->menu_btn[0], + priv->menu_btn[i - 1], ELM_FOCUS_LEFT); + elm_object_focus_next_object_set(priv->menu_btn[i - 1], + priv->menu_btn[0], ELM_FOCUS_RIGHT); + + return true; +} + +static bool _draw_bottom_area(struct _priv *priv) +{ + /* It will be implemented later */ + + return true; +} + +static void _draw_view_content(struct _priv *priv) +{ + if (!_draw_top_area(priv)) { + _ERR("Draw top area failed."); + return; + } + + if (!_draw_menu_area(priv)) { + _ERR("Draw menu area failed."); + return; + } + + if (!_draw_bottom_area(priv)) + _ERR("Draw bottom area failed."); +} + +static Evas_Object *_create(Evas_Object *win, void *data) +{ + struct _priv *priv; + Evas_Object *base; + + if (!win) { + _ERR("Get window object failed."); + return NULL; + } + + priv = calloc(1, sizeof(*priv)); + if (!priv) { + _ERR("Calloc failed."); + return NULL; + } + + base = elm_layout_add(win); + if (!base) { + _ERR("failed to create base object"); + free(priv); + return NULL; + } + elm_layout_file_set(base, EDJEFILE, GRP_VIEW_ACTION_MENU); + evas_object_size_hint_weight_set(base, + EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_win_resize_object_add(win, base); + + priv->base = base; + + if (!viewmgr_set_view_data(VIEW_ACTION_MENU, priv)) { + _ERR("Set view data failed."); + evas_object_del(base); + free(priv); + return NULL; + } + + _draw_view_content(priv); + + return base; +} + +static void _show(void *data) +{ + struct _priv *priv; + + if (!data) { + _ERR("Get data failed."); + return; + } + priv = data; + + if (priv->base) + evas_object_show(priv->base); +} + +static void _hide(void *data) +{ + struct _priv *priv; + + if (!data) { + _ERR("Get data failed."); + return; + } + priv = data; + + if (priv->base) + evas_object_hide(priv->base); +} + +static void _destroy(void *data) +{ + struct _priv *priv; + + if (!data) { + _ERR("Get data failed."); + return; + } + priv = data; + + if (priv->base) + evas_object_del(priv->base); + + free(priv); +} + +static view_class _vclass = { + .view_id = VIEW_ACTION_MENU, + .create = _create, + .show = _show, + .hide = _hide, + .destroy = _destroy, +}; + +view_class *view_action_menu_get_vclass(void) +{ + return &_vclass; +} -- 2.7.4