diff options
-rw-r--r-- | include/define.h | 2 | ||||
-rw-r--r-- | include/util/util.h | 1 | ||||
-rw-r--r-- | include/view/mplayer.h | 4 | ||||
-rw-r--r-- | res/edc/images/ic_music_list_play.png | bin | 0 -> 1027 bytes | |||
-rw-r--r-- | res/edc/images/ic_music_list_play_foc.png | bin | 0 -> 1709 bytes | |||
-rw-r--r-- | res/edc/mediahub-theme.edc | 1 | ||||
-rw-r--r-- | res/edc/view/mplayer.edc | 13 | ||||
-rw-r--r-- | res/edc/widgets/genlist.edc | 376 | ||||
-rw-r--r-- | src/util/util.c | 20 | ||||
-rw-r--r-- | src/view/mplayer.c | 214 |
10 files changed, 629 insertions, 2 deletions
diff --git a/include/define.h b/include/define.h index dc8be89..4edee07 100644 --- a/include/define.h +++ b/include/define.h @@ -51,6 +51,7 @@ #define COLOR_ITEM_SELECTED 64 136 211 255 #define COLOR_ITEM_BAR 190 190 190 255 #define COLOR_ITEM_BORDER 194 194 194 255 +#define COLOR_LIST_BG 244 244 244 255 /* part */ #define PART_ELM_TEXT_TITLE "elm.text.title" @@ -65,6 +66,7 @@ #define SIG_BTN_SELECTED "btn,selected" #define SIG_BTN_UNSELECTED "btn,unselected" #define SIG_ITEM_SELECTED "item,selected" +#define SIG_ITEM_UNSELECTED "item,unselected" #define SIG_SOURCE_EDC "edc" #define SIG_SOURCE_SRC "src" diff --git a/include/util/util.h b/include/util/util.h index c5b4afa..dd4bbb7 100644 --- a/include/util/util.h +++ b/include/util/util.h @@ -20,6 +20,7 @@ Evas_Object *util_add_box(Evas_Object *base); Evas_Object *util_add_gengrid(Evas_Object *base, int item_size_x, int item_size_y); +Evas_Object *util_add_genlist(Evas_Object *base); Evas_Object *util_add_image(Evas_Object *base, const char *file); Evas_Object *util_add_scroller(Evas_Object *base); diff --git a/include/view/mplayer.h b/include/view/mplayer.h index 660e780..297ba41 100644 --- a/include/view/mplayer.h +++ b/include/view/mplayer.h @@ -25,6 +25,7 @@ /* style */ #define STYLE_MPLAYER_PROGRESS "music_progress" +#define STYLE_MPLAYER_LIST "music_list" /* part */ #define PART_MPLAYER_BG "part.mplayer_bg" @@ -34,6 +35,7 @@ #define PART_MPLAYER_PROGRESS "part.mplayer_progress" #define PART_MPLAYER_TOTAL "part.mplayer_total" #define PART_MPLAYER_SLIDER "part.mplayer_slider" +#define PART_MPLAYER_LIST "part.mplayer_list" /* source */ #define SRC_BTN_MUSIC_SHUFFLE "shuffle" @@ -57,5 +59,7 @@ #define IMAGE_MUSIC_SHUFFLE_DIS_NORMAL "btn_music_contr_shuffle_dis.png" #define IMAGE_MUSIC_REPEAT_FOCUS "btn_music_contr_repeat_foc.png" #define IMAGE_MUSIC_REPEAT_NORMAL "btn_music_contr_repeat_nor.png" +#define IMAGE_MUSIC_LIST_PLAY "ic_music_list_play.png" +#define IMAGE_MUSIC_LIST_PLAY_FOC "ic_music_list_play_foc.png" #endif diff --git a/res/edc/images/ic_music_list_play.png b/res/edc/images/ic_music_list_play.png Binary files differnew file mode 100644 index 0000000..7a6ae5d --- /dev/null +++ b/res/edc/images/ic_music_list_play.png diff --git a/res/edc/images/ic_music_list_play_foc.png b/res/edc/images/ic_music_list_play_foc.png Binary files differnew file mode 100644 index 0000000..9392c0f --- /dev/null +++ b/res/edc/images/ic_music_list_play_foc.png diff --git a/res/edc/mediahub-theme.edc b/res/edc/mediahub-theme.edc index 4eb7b88..f1981b6 100644 --- a/res/edc/mediahub-theme.edc +++ b/res/edc/mediahub-theme.edc @@ -19,5 +19,6 @@ collections { #include "widgets/button.edc" #include "widgets/gengrid.edc" + #include "widgets/genlist.edc" #include "widgets/slider.edc" } diff --git a/res/edc/view/mplayer.edc b/res/edc/view/mplayer.edc index 1a4415f..21c9654 100644 --- a/res/edc/view/mplayer.edc +++ b/res/edc/view/mplayer.edc @@ -429,10 +429,21 @@ group { clip_to: "rightarea"; description { state: "default" 0.0; - color: COLOR_BASE_BG; + color: COLOR_LIST_BG; rel1.to: "rightarea"; rel2.to: "rightarea"; } } + part { + name: PART_MPLAYER_LIST; + type: SWALLOW; + scale: 1; + clip_to: "rightarea"; + description { + state: "default" 0.0; + rel1.to: "rightarea_bg"; + rel2.to: "rightarea_bg"; + } + } } } diff --git a/res/edc/widgets/genlist.edc b/res/edc/widgets/genlist.edc new file mode 100644 index 0000000..c93f86d --- /dev/null +++ b/res/edc/widgets/genlist.edc @@ -0,0 +1,376 @@ +/* + * 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 LIST_TRANSITION_TIME 0.30 + +group { + name: "elm/genlist/item/music_list/default"; + data.item: "selectraise" "on"; + data.item: "focusraise" "on"; + data.item: "texts" "elm.text.title elm.text.artist elm.text.playtime"; + data.item: "contents" "elm.swallow.icon"; + data.item: "focus_highlight" "on"; + images { + image: IMAGE_MUSIC_LIST_PLAY COMP; + image: IMAGE_MUSIC_LIST_PLAY_FOC COMP; + } + parts { + part { + name: "bg"; + type: RECT; + scale: 1; + description { + state: "default" 0.0; + min: 0 140; + color: COLOR_LIST_BG; + } + description { + state: "focused" 0.0; + inherit: "default" 0.0; + color: COLOR_ITEM_FOCUS; + } + } + part { + name: "left_padding"; + type: SPACER; + scale: 1; + description { + state: "default" 0.0; + min: 44 140; + rel1 { + to: "bg"; + relative: 0.0 0.0; + } + rel2 { + to: "bg"; + relative: 0.0 0.0; + } + fixed: 1 1; + align: 0.0 0.0; + } + } + part { + name: "image_bg"; + type: RECT; + scale: 1; + description { + state: "default" 0.0; + min: 0 140; + rel1 { + to: "left_padding"; + relative: 1.0 0.0; + } + rel2 { + to: "left_padding"; + relative: 1.0 0.0; + } + fixed: 1 1; + align: 0.0 0.0; + visible: 0; + } + description { + state: "default" 0.1; + inherit: "default" 0.0; + min: 40 140; + } + } + part { + name: "image_play"; + type: IMAGE; + scale: 1; + description { + state: "default" 0.0; + min: 40 40; + rel1 { + to: "image_bg"; + relative: 0.5 0.5; + } + rel2 { + to: "image_bg"; + relative: 0.5 0.5; + } + align: 0.5 0.5; + fixed: 1 1; + visible: 0; + } + description { + state: "default" 0.1; + inherit: "default" 0.0; + min: 40 40; + fixed: 1 1; + image.normal: IMAGE_MUSIC_LIST_PLAY; + visible: 1; + } + description { + state: "focused" 0.1; + inherit: "default" 0.0; + min: 40 40; + fixed: 1 1; + image.normal: IMAGE_MUSIC_LIST_PLAY_FOC; + visible: 1; + } + } + part { + name: "image_padding"; + type: SPACER; + description { + state: "default" 0.0; + min: 0 140; + rel1 { + to: "image_bg"; + relative: 1.0 0.0; + } + rel2 { + to: "image_bg"; + relative: 1.0 0.0; + } + fixed: 1 1; + align: 0.0 0.0; + } + description { + state: "default" 0.1; + inherit: "default" 0.0; + min: 28 140; + } + } + part { + name: "right_padding"; + type: SPACER; + scale: 1; + description { + state: "default" 0.0; + min: 40 140; + rel1 { + to: "bg"; + relative: 1.0 0.0; + } + rel2 { + to: "bg"; + relative: 1.0 0.0; + } + fixed: 1 1; + align: 1.0 0.0; + } + } + part { + name: "time_padding"; + type: SPACER; + scale: 1; + description { + state: "default" 0.0; + min: 0 140; + rel1 { + to: "right_padding"; + relative: 0.0 0.0; + } + rel2 { + to: "right_padding"; + relative: 0.0 0.0; + } + fixed: 1 1; + align: 0.0 0.0; + } + description { + state: "default" 0.1; + inherit: "default" 0.0; + min: 130 140; + rel1 { + to: "right_padding"; + relative: 1.0 0.0; + } + rel2 { + to: "right_padding"; + relative: 1.0 0.0; + } + align: 0.0 0.0; + fixed: 1 1; + } + } + part { + name: PART_ELM_TEXT_PLAYTIME; + type: TEXT; + scale: 1; + description { + state: "default" 0.0; + min: 130 0; + rel1 { + to: "time_padding"; + relative: 1.0 0.0; + } + rel2 { + to: "time_padding"; + relative: 1.0 1.0; + } + text { + font: FONT_LIGHT; + size: 28; + align: 1.0 0.5; + } + fixed: 1 0; + align: 1.0 0.0; + color: COLOR_TEXT_MENU; + } + description { + state: "focused" 0.0; + inherit: "default" 0.0; + color: COLOR_TEXT_FOCUS; + } + } + part { + name: PART_ELM_TEXT_TITLE; + type: TEXT; + scale: 1; + description { + state: "default" 0.0; + min: 0 68; + rel1 { + to: "image_padding"; + relative: 1.0 0.0; + } + rel2 { + to: PART_ELM_TEXT_PLAYTIME; + relative: 0.0 0.0; + } + text { + font: FONT_LIGHT; + size: 36; + align: 0.0 1.0; + } + fixed: 0 1; + align: 0.0 0.0; + color: COLOR_TEXT_INDEX; + } + description { + state: "focused" 0.0; + inherit: "default" 0.0; + color: COLOR_TEXT_FOCUS; + } + } + part { + name: PART_ELM_TEXT_ARTIST; + type: TEXT; + scale: 1; + description { + state: "default" 0.0; + min: 0 44; + rel1 { + to: PART_ELM_TEXT_TITLE; + relative: 0.0 1.0; + } + rel2 { + to: PART_ELM_TEXT_TITLE; + relative: 1.0 1.0; + } + text { + font: FONT_LIGHT; + size: 28; + align: 0.0 1.0; + } + fixed: 0 1; + align: 0.0 0.0; + color: COLOR_TEXT_MENU; + } + description { + state: "focused" 0.0; + inherit: "default" 0.0; + color: COLOR_TEXT_FOCUS; + } + } + } + script { + public focus_status = 0; + public select_status = 0; + } + programs { + program { + name: "go_active"; + signal: "elm,state,focused"; + source: "elm"; + script { + set_int(focus_status, 1); + set_state(PART:"bg", "focused", 0.0); + set_state(PART:PART_ELM_TEXT_TITLE, "focused", 0.0); + set_state(PART:PART_ELM_TEXT_ARTIST, "focused", 0.0); + set_state(PART:PART_ELM_TEXT_PLAYTIME, "focused", 0.0); + if (get_int(select_status) == 1) + set_state(PART:"image_play", "focused", 0.1); + else + set_state(PART:"image_play", "default", 0.0); + } + } + program { + name: "go_passive"; + signal: "elm,state,unfocused"; + source: "elm"; + script { + set_int(focus_status, 0); + set_state(PART:"bg", "default", 0.0); + set_state(PART:PART_ELM_TEXT_TITLE, "default", 0.0); + set_state(PART:PART_ELM_TEXT_ARTIST, "default", 0.0); + set_state(PART:PART_ELM_TEXT_PLAYTIME, "default", 0.0); + if (get_int(select_status) == 1) + set_state(PART:"image_play", "default", 0.1); + else + set_state(PART:"image_play", "default", 0.0); + } + } + program { + name: "go_select"; + signal: SIG_ITEM_SELECTED; + source: SIG_SOURCE_SRC; + script { + set_int(select_status, 1); + run_program(PROGRAM:"anim,select"); + } + } + program { + name: "anim,select"; + action: STATE_SET "default" 0.1; + target: "image_padding"; + target: "image_bg"; + target: "time_padding"; + transition: LINEAR LIST_TRANSITION_TIME; + after: "select,image"; + } + program { + name: "select,image"; + script { + if (get_int(focus_status) == 1) + set_state(PART:"image_play", "focused", 0.1); + else + set_state(PART:"image_play", "default", 0.1); + } + } + program { + name: "go_unselect"; + signal: SIG_ITEM_UNSELECTED; + source: SIG_SOURCE_SRC; + script { + set_int(select_status, 0); + set_state(PART:"image_play", "default", 0.0); + run_program(PROGRAM:"anim,unselect"); + } + } + program { + name: "anim,unselect"; + action: STATE_SET "default" 0.0; + target: "image_padding"; + target: "image_bg"; + target: "time_padding"; + transition: LINEAR LIST_TRANSITION_TIME; + } + } +} diff --git a/src/util/util.c b/src/util/util.c index 73f2488..8446b7a 100644 --- a/src/util/util.c +++ b/src/util/util.c @@ -70,6 +70,26 @@ Evas_Object *util_add_gengrid(Evas_Object *base, return grid; } +Evas_Object *util_add_genlist(Evas_Object *base) +{ + Evas_Object *list; + + list = elm_genlist_add(base); + if (!list) { + _ERR("failed to adding genlist"); + return NULL; + } + + evas_object_size_hint_weight_set(list, + EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + + elm_genlist_homogeneous_set(list, EINA_TRUE); + elm_genlist_select_mode_set(list, ELM_OBJECT_SELECT_MODE_ALWAYS); + elm_genlist_multi_select_set(list, EINA_FALSE); + + return list; +} + Evas_Object *util_add_image(Evas_Object *base, const char *file) { Evas_Object *image; diff --git a/src/view/mplayer.c b/src/view/mplayer.c index 90a89cb..c10468b 100644 --- a/src/view/mplayer.c +++ b/src/view/mplayer.c @@ -37,6 +37,11 @@ #define PART_MUSIC_BTN "control_btn" #define PLAY_BTN_LOC 2 +struct _list_data { + app_media *am; + Elm_Object_Item *item; +}; + struct _playlist { Eina_List *list; int cur; @@ -46,6 +51,9 @@ struct _priv { Evas_Object *win; Evas_Object *base; Evas_Object *thumb; + Evas_Object *list; + + Eina_List *item_list; struct _playlist playlist; struct playermgr *player; @@ -129,6 +137,20 @@ static void _media_test(struct _priv *priv) } /* FIXME: test function end */ +static void _draw_playlist(struct _priv *priv) +{ + struct _list_data *ld; + + ld = eina_list_nth(priv->item_list, priv->playlist.cur); + if (!ld) { + _ERR("failed to get list data"); + return; + } + + elm_genlist_item_bring_in(ld->item, ELM_GENLIST_ITEM_SCROLLTO_IN); + elm_genlist_realized_items_update(priv->list); +} + static void _draw_thumbnail(struct _priv *priv, app_media_info *mi) { elm_image_file_set(priv->thumb, mi->thumbnail_path, NULL); @@ -179,8 +201,10 @@ static void _mplayer_show(struct _priv *priv) app_media_info *mi; mi = _get_current_media_info(priv); - if (!mi) + if (!mi) { _ERR("failed to getting media info"); + return; + } ctl = priv->ctl; ctl->ops->show(ctl->handle); @@ -188,6 +212,7 @@ static void _mplayer_show(struct _priv *priv) _draw_thumbnail(priv, mi); _draw_music_info(priv, mi); _draw_progressbar(priv, mi); + _draw_playlist(priv); app_contents_recent_add(CONTENTS_MEDIA, mi->media_id); } @@ -228,6 +253,23 @@ static void _mplayer_next(struct _priv *priv) _mplayer_show(priv); } +static void _mplayer_set_current(struct _priv *priv, int index) +{ + int total; + + if (index < 0) + return; + + total = eina_list_count(priv->playlist.list); + + if (index >= total) + return; + + priv->playlist.cur = index; + + _mplayer_show(priv); +} + static int _player_get_position(void *data) { struct _priv *priv; @@ -351,6 +393,160 @@ static void _callback_music(void *data, const char *ev) } } +static void _list_free(struct _priv *priv) +{ + elm_genlist_clear(priv->list); + + eina_list_free(priv->item_list); + priv->item_list = NULL; +} + +static void _list_item_del(void *data, Evas_Object *obj) +{ + free(data); +} + +static char *_list_text_get(void *data, Evas_Object *obj, const char *part) +{ + struct _list_data *ld; + app_media *am; + app_media_info *mi; + Elm_Object_Item *item; + char buf[1024]; + + if (!data) + return NULL; + + ld = data; + am = ld->am; + item = ld->item; + + mi = app_media_get_info(am); + if (!mi) { + _ERR("failed to get media info"); + return NULL; + } + + if (!strcmp(part, PART_ELM_TEXT_TITLE)) { + snprintf(buf, sizeof(buf), "%02d. %s", + elm_genlist_item_index_get(item), mi->title); + } else if (!strcmp(part, PART_ELM_TEXT_ARTIST)) { + snprintf(buf, sizeof(buf), "%s / %s", + mi->audio->artist, mi->audio->album); + } else if (!strcmp(part, PART_ELM_TEXT_PLAYTIME)) { + util_time_string(buf, sizeof(buf), mi->audio->duration, false); + } else { + return NULL; + } + + return strdup(buf); +} + +static void _list_selected(int id, void *data, + Evas_Object *obj, Elm_Object_Item *it) +{ + struct _priv *priv; + int index; + + if (!data || !it) + return; + + priv = data; + index = elm_genlist_item_index_get(it) - 1; + + if (priv->playlist.cur != index) { + _mplayer_set_current(priv, index); + _player_next(priv); + } +} + +static void _list_realized(int id, void *data, + Evas_Object *obj, Elm_Object_Item *it) +{ + struct _priv *priv; + int index; + + if (!data || !it) + return; + + priv = data; + index = elm_genlist_item_index_get(it) - 1; + + if (priv->playlist.cur == index) { + elm_object_item_signal_emit(it, + SIG_ITEM_SELECTED, SIG_SOURCE_SRC); + } else { + elm_object_item_signal_emit(it, + SIG_ITEM_UNSELECTED, SIG_SOURCE_SRC); + } +} + +static void _list_mouse_move(int id, void *data, Evas *e, Evas_Object *obj, + Evas_Event_Mouse_Move *ev) +{ + Elm_Object_Item *it; + + if (!data || !ev) + return; + + it = elm_genlist_at_xy_item_get(obj, ev->cur.canvas.x, + ev->cur.canvas.y, NULL); + + if (!it) + return; + + if (!elm_object_item_focus_get(it)) + elm_object_item_focus_set(it, EINA_TRUE); +} + +static input_handler _list_handler = { + .realized = _list_realized, + .selected = _list_selected, + .mouse_move = _list_mouse_move, +}; + +static void _add_playlist_item(struct _priv *priv) +{ + Elm_Genlist_Item_Class *ic; + Elm_Object_Item *item; + app_media *am; + int i; + int total; + + _list_free(priv); + + ic = elm_genlist_item_class_new(); + if (!ic) { + _ERR("failed to get genlist item class"); + return; + } + + ic->item_style = STYLE_MPLAYER_LIST; + ic->func.text_get = _list_text_get; + ic->func.content_get = NULL; + ic->func.state_get = NULL; + ic->func.del = _list_item_del; + + total = eina_list_count(priv->playlist.list); + + for (i = 0; i < total; i++) { + struct _list_data *ld; + + ld = calloc(1, sizeof(*ld)); + if (!ld) + continue; + + am = eina_list_nth(priv->playlist.list, i); + ld->am = am; + + item = elm_genlist_item_append(priv->list, ic, ld, NULL, + ELM_GENLIST_ITEM_NONE, NULL, NULL); + ld->item = item; + + priv->item_list = eina_list_append(priv->item_list, ld); + } +} + static bool _ui_init(struct _priv *priv) { struct controller *ctl; @@ -394,6 +590,15 @@ static bool _ui_init(struct _priv *priv) priv->progress = prog; + obj = util_add_genlist(priv->base); + if (!obj) + goto err; + + elm_object_part_content_set(priv->base, PART_MPLAYER_LIST, obj); + inputmgr_add_callback(obj, 0, &_list_handler, priv); + + priv->list = obj; + return true; err: @@ -462,6 +667,7 @@ static Evas_Object *_create(Evas_Object *win, void *data) /* FIXME */ _media_test(priv); + _add_playlist_item(priv); viewmgr_set_view_data(VIEW_MPLAYER, priv); @@ -524,6 +730,8 @@ static void _update(void *view_data, int update_type, void *data) priv->playlist.list = vdata->list; priv->playlist.cur = vdata->index; + + _add_playlist_item(priv); } static void _destroy(void *view_data) @@ -537,6 +745,10 @@ static void _destroy(void *view_data) priv = view_data; + _list_free(priv); + inputmgr_remove_callback(priv->list, &_list_handler); + + _player_stop(priv); playermgr_destroy(priv->player); controller_destroy(priv->ctl); |