2 * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #include <Elementary.h>
19 #include <app_debug.h>
22 #include <media_content.h>
23 #include <media_info.h>
25 #include <app_media.h>
26 #include <app_contents.h>
30 #include "util/controller.h"
31 #include "util/playermgr.h"
32 #include "util/progressbar.h"
33 #include "util/util.h"
35 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
37 #define STYLE_MUSIC_BTN "music_btn"
38 #define PART_MUSIC_BTN "control_btn"
39 #define PLAY_BTN_LOC 2
49 Elm_Object_Item *item;
57 enum _repeat_state repeat;
68 struct _playlist playlist;
69 struct playermgr *player;
70 struct progressbar *progress;
71 struct controller *ctl;
79 static struct _btn_info btn_player[] = {
81 .name = SRC_BTN_MUSIC_SHUFFLE,
85 .name = SRC_BTN_MUSIC_PREV,
89 .name = SRC_BTN_MUSIC_PLAY,
93 .name = SRC_BTN_MUSIC_NEXT,
97 .name = SRC_BTN_MUSIC_REPEAT,
102 static void _add_to_recent(struct _priv *priv)
107 am = eina_list_nth(priv->playlist.list, priv->playlist.cur);
109 _ERR("failed to get app_media");
113 mi = app_media_get_info(am);
115 _ERR("failed to getting media info");
119 app_contents_recent_add(CONTENTS_MEDIA, mi->media_id);
121 app_media_update(am);
124 static void _draw_playlist(struct _priv *priv)
126 struct _list_data *ld;
128 ld = eina_list_nth(priv->item_list, priv->playlist.cur);
130 _ERR("failed to get list data");
134 if (!elm_object_focus_get(priv->list)) {
135 elm_genlist_item_bring_in(ld->item,
136 ELM_GENLIST_ITEM_SCROLLTO_IN);
139 elm_genlist_realized_items_update(priv->list);
142 static void _draw_thumbnail(struct _priv *priv, app_media_info *mi)
146 if (mi->thumbnail_path)
147 path = mi->thumbnail_path;
149 path = IMAGE_MUSIC_THUMBNAIL;
151 elm_image_file_set(priv->thumb, path, NULL);
152 elm_object_part_content_set(priv->base,
153 PART_MPLAYER_THUMB, priv->thumb);
156 static void _draw_music_info(struct _priv *priv, app_media_info *mi)
158 char buf[128] = {0,};
160 snprintf(buf, sizeof(buf), "%s / %s",
161 mi->audio->artist, mi->audio->album);
163 elm_object_part_text_set(priv->base, PART_MPLAYER_TITLE, mi->title);
164 elm_object_part_text_set(priv->base, PART_MPLAYER_INFO, buf);
167 static void _draw_progressbar(struct _priv *priv, app_media_info *mi)
169 progressbar_show(priv->progress);
172 static app_media *_playlist_get_media(Eina_List *list, int index)
176 am = eina_list_nth(list, index);
178 _ERR("failed to get app_media");
185 static app_media_info *_playlist_get_current_media_info(struct _priv *priv)
190 am = eina_list_nth(priv->playlist.list, priv->playlist.cur);
192 _ERR("failed to get app_media");
196 mi = app_media_get_info(am);
198 _ERR("failed to getting media info");
205 static int _playlist_get_index(Eina_List *dest, Eina_List *src, int index)
209 am = _playlist_get_media(src, index);
211 return util_get_media_index(dest, am);
214 static void _playlist_set_list(struct _priv *priv, bool shuffle, int index)
221 _ERR("playlist is NULL");
225 am = _playlist_get_media(p->list, index);
226 eina_list_free(p->list);
228 p->list = eina_list_clone(p->list_org);
231 p->list = eina_list_shuffle(p->list, NULL);
233 p->cur = util_get_media_index(p->list, am);
234 p->shuffle = shuffle;
237 static void _playlist_set_repeat_mode(struct _priv *priv)
243 _ERR("playlist is NULL");
249 p->repeat = REPEAT_ONE;
252 p->repeat = REPEAT_NONE;
255 p->repeat = REPEAT_ALL;
258 _ERR("Unknown repeat state");
259 p->repeat = REPEAT_ALL;
264 static void _update_info(struct _priv *priv, app_media_info *mi)
266 struct view_update_data vdata;
268 /* update progressbar */
269 progressbar_reset(priv->progress, 0, mi->audio->duration);
271 /* update play info */
272 vdata.index = _playlist_get_index(priv->playlist.list_org,
273 priv->playlist.list, priv->playlist.cur);
274 viewmgr_update_view(VIEW_BASE, UPDATE_PLAY_INFO, &vdata);
277 _add_to_recent(priv);
280 static void _mplayer_show(struct _priv *priv)
282 struct controller *ctl;
285 mi = _playlist_get_current_media_info(priv);
287 _ERR("failed to getting media info");
291 if (viewmgr_get_view_state(VIEW_MPLAYER) != VIEW_STATE_VISIBLE) {
292 _update_info(priv, mi);
297 ctl->ops->show(ctl->handle);
299 _draw_thumbnail(priv, mi);
300 _draw_music_info(priv, mi);
301 _draw_progressbar(priv, mi);
302 _draw_playlist(priv);
304 _update_info(priv, mi);
307 static void _mplayer_hide(struct _priv *priv)
309 struct controller *ctl;
312 ctl->ops->hide(ctl->handle);
315 static bool _mplayer_prev(struct _priv *priv)
319 total = eina_list_count(priv->playlist.list);
321 switch (priv->playlist.repeat) {
323 if (priv->playlist.cur != 0)
324 priv->playlist.cur--;
326 priv->playlist.cur = total - 1;
329 if (priv->playlist.cur != 0)
330 priv->playlist.cur--;
335 _ERR("Unknown repeat state");
344 static bool _mplayer_next(struct _priv *priv)
349 total = eina_list_count(priv->playlist.list);
353 switch (priv->playlist.repeat) {
355 if (priv->playlist.cur != total - 1)
356 priv->playlist.cur++;
358 priv->playlist.cur = 0;
361 if (priv->playlist.cur != total - 1)
362 priv->playlist.cur++;
364 priv->playlist.cur = 0;
371 _ERR("Unknown repeat state");
380 static void _mplayer_set_current(struct _priv *priv, int index)
387 total = eina_list_count(priv->playlist.list);
392 priv->playlist.cur = index;
397 static int _player_get_position(void *data)
406 return playermgr_get_position(priv->player);
409 static void _player_play_pause(struct _priv *priv)
412 player_state_e state;
414 playermgr_get_state(priv->player, &state);
417 case PLAYER_STATE_PAUSED:
418 progressbar_resume(priv->progress);
419 playermgr_resume(priv->player);
421 case PLAYER_STATE_PLAYING:
422 progressbar_pause(priv->progress);
423 playermgr_pause(priv->player);
425 case PLAYER_STATE_IDLE:
426 case PLAYER_STATE_READY:
427 mi = _playlist_get_current_media_info(priv);
429 _ERR("failed to getting media info");
433 progressbar_start(priv->progress);
434 playermgr_play(priv->player, mi->file_path, 0);
437 _ERR("player was not created");
442 static void _player_next(struct _priv *priv)
445 player_state_e state;
447 playermgr_get_state(priv->player, &state);
450 case PLAYER_STATE_PAUSED:
451 case PLAYER_STATE_IDLE:
452 case PLAYER_STATE_READY:
453 progressbar_stop(priv->progress);
454 playermgr_stop(priv->player);
456 case PLAYER_STATE_PLAYING:
457 mi = _playlist_get_current_media_info(priv);
459 _ERR("failed to getting media info");
463 progressbar_start(priv->progress);
464 playermgr_play(priv->player, mi->file_path, 0);
467 _ERR("player was not created");
472 static void _player_pause(struct _priv *priv)
474 player_state_e state;
475 struct controller *ctl;
477 playermgr_get_state(priv->player, &state);
480 case PLAYER_STATE_PLAYING:
481 progressbar_pause(priv->progress);
482 playermgr_pause(priv->player);
484 case PLAYER_STATE_PAUSED:
485 case PLAYER_STATE_IDLE:
486 case PLAYER_STATE_READY:
489 _ERR("player was not created");
494 ctl->ops->signal(ctl->handle, PLAY_BTN_LOC, SIG_SET_PLAY);
497 static void _player_play(struct _priv *priv)
500 player_state_e state;
502 struct controller *ctl;
504 mi = _playlist_get_current_media_info(priv);
506 _ERR("failed to getting media info");
510 playermgr_get_state(priv->player, &state);
513 case PLAYER_STATE_IDLE:
514 case PLAYER_STATE_READY:
515 progressbar_start(priv->progress);
516 playermgr_play(priv->player, mi->file_path, 0);
518 case PLAYER_STATE_PAUSED:
519 path = playermgr_get_path(priv->player);
520 if (path && !strcmp(mi->file_path, path))
521 playermgr_resume(priv->player);
523 playermgr_play(priv->player, mi->file_path, 0);
525 progressbar_resume(priv->progress);
527 case PLAYER_STATE_PLAYING:
528 path = playermgr_get_path(priv->player);
529 if (path && !strcmp(mi->file_path, path))
532 progressbar_start(priv->progress);
533 playermgr_play(priv->player, mi->file_path, 0);
536 _ERR("player was not created");
541 ctl->ops->signal(ctl->handle, PLAY_BTN_LOC, SIG_SET_PAUSE);
544 static void _player_stop(struct _priv *priv)
546 struct controller *ctl;
548 progressbar_stop(priv->progress);
549 playermgr_stop(priv->player);
552 ctl->ops->signal(ctl->handle, PLAY_BTN_LOC, SIG_SET_PLAY);
555 static void _player_complete_cb(void *data)
565 r = _mplayer_next(priv);
572 static struct progressbar_ops _progressbar_ops = {
573 .get_value = _player_get_position,
576 static void _pop_view(struct _priv *priv)
578 struct view_update_data vdata;
580 if (viewmgr_active_view_count() > 1) {
581 vdata.index = _playlist_get_index(priv->playlist.list_org,
582 priv->playlist.list, priv->playlist.cur);
584 viewmgr_update_view(VIEW_BASE, UPDATE_FOCUS, &vdata);
589 if (viewmgr_active_view_count() == 0)
593 static void _key_down(int id, void *data, Evas *e, Evas_Object *obj,
594 Evas_Event_Key_Down *ev)
604 if (!strcmp(ev->keyname, KEY_BACK) ||
605 !strcmp(ev->keyname, KEY_BACK_REMOTE)) {
607 } else if (!strcmp(ev->keyname, KEY_PLAY)) {
609 } else if (!strcmp(ev->keyname, KEY_PAUSE)) {
611 } else if (!strcmp(ev->keyname, KEY_STOP)) {
613 } else if (!strcmp(ev->keyname, KEY_NEXT)) {
614 r = _mplayer_next(priv);
619 } else if (!strcmp(ev->keyname, KEY_PREVIOUS)) {
625 static void _list_set_focus(struct _priv *priv)
627 struct _list_data *ld;
629 ld = eina_list_nth(priv->item_list, priv->playlist.cur);
631 _ERR("failed to get list data");
635 elm_object_item_focus_set(ld->item, EINA_TRUE);
638 static void _list_free(struct _priv *priv)
640 elm_genlist_clear(priv->list);
642 eina_list_free(priv->item_list);
643 priv->item_list = NULL;
646 static void _list_item_del(void *data, Evas_Object *obj)
651 static char *_list_text_get(void *data, Evas_Object *obj, const char *part)
653 struct _list_data *ld;
662 index = elm_genlist_item_index_get(ld->item);
664 mi = app_media_get_info(ld->am);
666 _ERR("failed to get media info");
670 if (!strcmp(part, PART_ELM_TEXT_TITLE) ||
671 !strcmp(part, PART_ELM_TEXT_TITLE2)) {
672 snprintf(buf, sizeof(buf), "%02d. %s", index, mi->title);
673 } else if (!strcmp(part, PART_ELM_TEXT_ARTIST)) {
674 snprintf(buf, sizeof(buf), "%s / %s",
675 mi->audio->artist, mi->audio->album);
676 } else if (!strcmp(part, PART_ELM_TEXT_PLAYTIME)) {
677 util_time_string(buf, sizeof(buf), mi->audio->duration, false);
685 static Evas_Object *_list_content_get(void *data,
686 Evas_Object *obj, const char *part)
688 struct _list_data *ld;
697 mi = app_media_get_info(ld->am);
699 _ERR("failed to get media info");
704 if (!strcmp(part, PART_ELM_SWALLOW_FAVORITE)) {
708 image = util_add_image(obj, IMAGE_MUSIC_LIST_FAVORITE);
710 _ERR("failed to create image object");
714 evas_object_show(image);
720 static void _list_selected(int id, void *data,
721 Evas_Object *obj, Elm_Object_Item *it)
730 index = elm_genlist_item_index_get(it) - 1;
732 if (priv->playlist.cur != index)
733 _mplayer_set_current(priv, index);
738 static void _list_realized(int id, void *data,
739 Evas_Object *obj, Elm_Object_Item *it)
748 index = elm_genlist_item_index_get(it) - 1;
750 if (priv->playlist.cur == index) {
751 elm_object_item_signal_emit(it,
752 SIG_ITEM_SELECTED, SIG_SOURCE_SRC);
754 elm_object_item_signal_emit(it,
755 SIG_ITEM_UNSELECTED, SIG_SOURCE_SRC);
759 static void _list_unrealized(int id, void *data,
760 Evas_Object *obj, Elm_Object_Item *it)
765 elm_object_item_signal_emit(it, SIG_ELM_UNFOCUSED, SIG_SOURCE_ELM);
768 static void _list_mouse_move(int id, void *data, Evas *e, Evas_Object *obj,
769 Evas_Event_Mouse_Move *ev)
776 it = elm_genlist_at_xy_item_get(obj, ev->cur.canvas.x,
777 ev->cur.canvas.y, NULL);
782 if (!elm_object_item_focus_get(it))
783 elm_object_item_focus_set(it, EINA_TRUE);
786 static input_handler _list_handler = {
787 .realized = _list_realized,
788 .unrealized = _list_unrealized,
789 .selected = _list_selected,
790 .mouse_move = _list_mouse_move,
791 .key_down = _key_down,
794 static input_handler _btn_handler = {
795 .key_down = _key_down,
798 static void _add_playlist_item(struct _priv *priv)
800 Elm_Genlist_Item_Class *ic;
801 Elm_Object_Item *item;
808 ic = elm_genlist_item_class_new();
810 _ERR("failed to get genlist item class");
814 ic->item_style = STYLE_MPLAYER_LIST;
815 ic->func.text_get = _list_text_get;
816 ic->func.content_get = _list_content_get;
817 ic->func.state_get = NULL;
818 ic->func.del = _list_item_del;
820 total = eina_list_count(priv->playlist.list);
822 for (i = 0; i < total; i++) {
823 struct _list_data *ld;
825 ld = calloc(1, sizeof(*ld));
829 am = eina_list_nth(priv->playlist.list, i);
832 item = elm_genlist_item_append(priv->list, ic, ld, NULL,
833 ELM_GENLIST_ITEM_NONE, NULL, NULL);
836 priv->item_list = eina_list_append(priv->item_list, ld);
840 static void _callback_music(void *data, const char *ev)
850 if (!strcmp(ev, SRC_BTN_MUSIC_PREV)) {
853 } else if (!strcmp(ev, SRC_BTN_MUSIC_NEXT)) {
854 r = _mplayer_next(priv);
859 } else if (!strcmp(ev, SRC_BTN_MUSIC_PLAY)) {
860 _player_play_pause(priv);
861 } else if (!strcmp(ev, SRC_BTN_MUSIC_SHUFFLE)) {
862 _playlist_set_list(priv, !priv->playlist.shuffle,
864 _add_playlist_item(priv);
866 _mplayer_set_current(priv, priv->playlist.cur);
868 } else if (!strcmp(ev, SRC_BTN_MUSIC_REPEAT)) {
869 _playlist_set_repeat_mode(priv);
873 static bool _ui_init(struct _priv *priv)
875 struct controller *ctl;
876 struct progressbar *prog;
880 obj = elm_image_add(priv->base);
882 _ERR("failed to adding image");
888 ctl = controller_create(priv->base);
890 _ERR("failed to create controller");
894 for (i = 0; i < ARRAY_SIZE(btn_player); i++) {
895 ctl->ops->add_control(ctl->handle,
896 btn_player[i].name, btn_player[i].loc,
897 STYLE_MUSIC_BTN, PART_MUSIC_BTN);
899 obj = ctl->ops->get_object(ctl->handle, i);
901 inputmgr_add_callback(obj, 0, &_btn_handler, priv);
904 ctl->ops->add_callback(ctl->handle, _callback_music, priv);
908 prog = progressbar_create(priv->base, STYLE_MPLAYER_PROGRESS);
910 _ERR("failed to adding progressbar");
914 progressbar_set_parts(prog, PART_MPLAYER_SLIDER, PART_MPLAYER_TOTAL,
915 PART_MPLAYER_PROGRESS, "");
916 progressbar_set_ops(prog, &_progressbar_ops, priv);
918 priv->progress = prog;
920 obj = util_add_genlist(priv->base);
924 elm_object_part_content_set(priv->base, PART_MPLAYER_LIST, obj);
925 inputmgr_add_callback(obj, 0, &_list_handler, priv);
932 controller_destroy(ctl);
936 static Evas_Object *_create(Evas_Object *win, void *data)
940 struct playermgr *player;
944 _ERR("failed to get win object");
948 priv = calloc(1, sizeof(*priv));
950 _ERR("failed to allocate priv");
954 base = elm_layout_add(win);
956 _ERR("failed to create base object");
960 elm_layout_file_set(base, EDJEFILE, GRP_MPLAYER_VIEW);
962 evas_object_size_hint_weight_set(base,
963 EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
964 elm_win_resize_object_add(win, base);
969 priv->playlist.list = NULL;
970 priv->playlist.list_org = NULL;
971 priv->playlist.cur = 0;
972 priv->playlist.shuffle = false;
973 priv->playlist.repeat = REPEAT_ALL;
975 player = playermgr_create(NULL);
977 _ERR("failed to create player");
981 r = playermgr_set_completed_cb(player, _player_complete_cb, priv);
983 _ERR("failed to set callback");
984 playermgr_destroy(player);
988 priv->player = player;
992 _ERR("failed to init UI");
993 playermgr_destroy(player);
997 viewmgr_set_view_data(VIEW_MPLAYER, priv);
1006 static void _show(void *view_data)
1011 _ERR("failed to get view data");
1017 media_content_connect();
1019 _mplayer_show(priv);
1021 _list_set_focus(priv);
1024 evas_object_show(priv->base);
1027 static void _hide(void *view_data)
1032 _ERR("failed to get view data");
1038 _mplayer_hide(priv);
1040 media_content_disconnect();
1042 evas_object_hide(priv->base);
1045 static void _update(void *view_data, int update_type, void *data)
1048 struct view_update_data *vdata;
1051 _ERR("failed to get view data");
1058 switch (update_type) {
1059 case UPDATE_CONTENT:
1063 if (priv->playlist.list_org != vdata->list) {
1064 priv->playlist.list_org = vdata->list;
1065 priv->playlist.list = eina_list_clone(vdata->list);
1067 _playlist_set_list(priv,
1068 priv->playlist.shuffle, vdata->index);
1070 priv->playlist.cur = _playlist_get_index(
1071 priv->playlist.list,
1072 vdata->list, vdata->index);
1075 _add_playlist_item(priv);
1085 static void _pause(void *view_data)
1090 _ERR("failed to get view data");
1099 static void _destroy(void *view_data)
1102 struct controller *ctl;
1107 _ERR("failed to get view data");
1115 for (i = 0; i < ARRAY_SIZE(btn_player); i++) {
1116 obj = ctl->ops->get_object(ctl->handle, i);
1118 inputmgr_remove_callback(obj, &_btn_handler);
1121 eina_list_free(priv->playlist.list);
1124 inputmgr_remove_callback(priv->list, &_list_handler);
1127 playermgr_destroy(priv->player);
1129 controller_destroy(priv->ctl);
1130 progressbar_destroy(priv->progress);
1132 evas_object_del(priv->base);
1137 static view_class _vclass = {
1138 .view_id = VIEW_MPLAYER,
1144 .destroy = _destroy,
1147 view_class *view_mplayer_get_vclass(void)