mplayer: adds support the remote controller
[profile/tv/apps/native/air_mediahub.git] / src / view / mplayer.c
1 /*
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 #include <app.h>
18 #include <Elementary.h>
19 #include <app_debug.h>
20 #include <viewmgr.h>
21 #include <inputmgr.h>
22 #include <media_content.h>
23 #include <media_info.h>
24 #include <player.h>
25 #include <app_media.h>
26 #include <app_contents.h>
27
28 #include "define.h"
29 #include "view.h"
30 #include "util/controller.h"
31 #include "util/playermgr.h"
32 #include "util/progressbar.h"
33 #include "util/util.h"
34
35 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
36
37 #define STYLE_MUSIC_BTN "music_btn"
38 #define PART_MUSIC_BTN "control_btn"
39 #define PLAY_BTN_LOC 2
40
41 enum _repeat_state {
42         REPEAT_ALL,
43         REPEAT_ONE,
44         REPEAT_NONE
45 };
46
47 struct _list_data {
48         app_media *am;
49         Elm_Object_Item *item;
50 };
51
52 struct _playlist {
53         Eina_List *list;
54         Eina_List *list_org;
55         int cur;
56         bool shuffle;
57         enum _repeat_state repeat;
58 };
59
60 struct _priv {
61         Evas_Object *win;
62         Evas_Object *base;
63         Evas_Object *thumb;
64         Evas_Object *list;
65
66         Eina_List *item_list;
67
68         struct _playlist playlist;
69         struct playermgr *player;
70         struct progressbar *progress;
71         struct controller *ctl;
72 };
73
74 struct _btn_info {
75         const char *name;
76         int loc;
77 };
78
79 static struct _btn_info btn_player[] = {
80         {
81                 .name = SRC_BTN_MUSIC_SHUFFLE,
82                 .loc = 0,
83         },
84         {
85                 .name = SRC_BTN_MUSIC_PREV,
86                 .loc = 1,
87         },
88         {
89                 .name = SRC_BTN_MUSIC_PLAY,
90                 .loc = 2,
91         },
92         {
93                 .name = SRC_BTN_MUSIC_NEXT,
94                 .loc = 3,
95         },
96         {
97                 .name = SRC_BTN_MUSIC_REPEAT,
98                 .loc = 4,
99         },
100 };
101
102 static void _add_to_recent(struct _priv *priv)
103 {
104         app_media *am;
105         app_media_info *mi;
106
107         am = eina_list_nth(priv->playlist.list, priv->playlist.cur);
108         if (!am) {
109                 _ERR("failed to get app_media");
110                 return;
111         }
112
113         mi = app_media_get_info(am);
114         if (!mi) {
115                 _ERR("failed to getting media info");
116                 return;
117         }
118
119         app_contents_recent_add(CONTENTS_MEDIA, mi->media_id);
120
121         app_media_update(am);
122 }
123
124 static void _draw_playlist(struct _priv *priv)
125 {
126         struct _list_data *ld;
127
128         ld = eina_list_nth(priv->item_list, priv->playlist.cur);
129         if (!ld) {
130                 _ERR("failed to get list data");
131                 return;
132         }
133
134         if (!elm_object_focus_get(priv->list)) {
135                 elm_genlist_item_bring_in(ld->item,
136                                 ELM_GENLIST_ITEM_SCROLLTO_IN);
137         }
138
139         elm_genlist_realized_items_update(priv->list);
140 }
141
142 static void _draw_thumbnail(struct _priv *priv, app_media_info *mi)
143 {
144         char *path;
145
146         if (mi->thumbnail_path)
147                 path = mi->thumbnail_path;
148         else
149                 path = IMAGE_MUSIC_THUMBNAIL;
150
151         elm_image_file_set(priv->thumb, path, NULL);
152         elm_object_part_content_set(priv->base,
153                         PART_MPLAYER_THUMB, priv->thumb);
154 }
155
156 static void _draw_music_info(struct _priv *priv, app_media_info *mi)
157 {
158         char buf[128] = {0,};
159
160         snprintf(buf, sizeof(buf), "%s / %s",
161                         mi->audio->artist, mi->audio->album);
162
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);
165 }
166
167 static void _draw_progressbar(struct _priv *priv, app_media_info *mi)
168 {
169         progressbar_show(priv->progress);
170 }
171
172 static app_media *_playlist_get_media(Eina_List *list, int index)
173 {
174         app_media *am;
175
176         am = eina_list_nth(list, index);
177         if (!am) {
178                 _ERR("failed to get app_media");
179                 return NULL;
180         }
181
182         return am;
183 }
184
185 static app_media_info *_playlist_get_current_media_info(struct _priv *priv)
186 {
187         app_media *am;
188         app_media_info *mi;
189
190         am = eina_list_nth(priv->playlist.list, priv->playlist.cur);
191         if (!am) {
192                 _ERR("failed to get app_media");
193                 return NULL;
194         }
195
196         mi = app_media_get_info(am);
197         if (!mi) {
198                 _ERR("failed to getting media info");
199                 return NULL;
200         }
201
202         return mi;
203 }
204
205 static int _playlist_get_index(Eina_List *dest, Eina_List *src, int index)
206 {
207         app_media *am;
208
209         am = _playlist_get_media(src, index);
210
211         return util_get_media_index(dest, am);
212 }
213
214 static void _playlist_set_list(struct _priv *priv, bool shuffle, int index)
215 {
216         struct _playlist *p;
217         app_media *am;
218
219         p = &priv->playlist;
220         if (!p) {
221                 _ERR("playlist is NULL");
222                 return;
223         }
224
225         am = _playlist_get_media(p->list, index);
226         eina_list_free(p->list);
227
228         p->list = eina_list_clone(p->list_org);
229
230         if (shuffle)
231                 p->list = eina_list_shuffle(p->list, NULL);
232
233         p->cur = util_get_media_index(p->list, am);
234         p->shuffle = shuffle;
235 }
236
237 static void _playlist_set_repeat_mode(struct _priv *priv)
238 {
239         struct _playlist *p;
240
241         p = &priv->playlist;
242         if (!p) {
243                 _ERR("playlist is NULL");
244                 return;
245         }
246
247         switch (p->repeat) {
248         case REPEAT_ALL:
249                 p->repeat = REPEAT_ONE;
250                 break;
251         case REPEAT_ONE:
252                 p->repeat = REPEAT_NONE;
253                 break;
254         case REPEAT_NONE:
255                 p->repeat = REPEAT_ALL;
256                 break;
257         default:
258                 _ERR("Unknown repeat state");
259                 p->repeat = REPEAT_ALL;
260                 break;
261         }
262 }
263
264 static void _update_info(struct _priv *priv, app_media_info *mi)
265 {
266         struct view_update_data vdata;
267
268         /* update progressbar */
269         progressbar_reset(priv->progress, 0, mi->audio->duration);
270
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);
275
276         /* update history */
277         _add_to_recent(priv);
278 }
279
280 static void _mplayer_show(struct _priv *priv)
281 {
282         struct controller *ctl;
283         app_media_info *mi;
284
285         mi = _playlist_get_current_media_info(priv);
286         if (!mi) {
287                 _ERR("failed to getting media info");
288                 return;
289         }
290
291         if (viewmgr_get_view_state(VIEW_MPLAYER) != VIEW_STATE_VISIBLE) {
292                 _update_info(priv, mi);
293                 return;
294         }
295
296         ctl = priv->ctl;
297         ctl->ops->show(ctl->handle);
298
299         _draw_thumbnail(priv, mi);
300         _draw_music_info(priv, mi);
301         _draw_progressbar(priv, mi);
302         _draw_playlist(priv);
303
304         _update_info(priv, mi);
305 }
306
307 static void _mplayer_hide(struct _priv *priv)
308 {
309         struct controller *ctl;
310
311         ctl = priv->ctl;
312         ctl->ops->hide(ctl->handle);
313 }
314
315 static bool _mplayer_prev(struct _priv *priv)
316 {
317         int total;
318
319         total = eina_list_count(priv->playlist.list);
320
321         switch (priv->playlist.repeat) {
322         case REPEAT_ALL:
323                 if (priv->playlist.cur != 0)
324                         priv->playlist.cur--;
325                 else
326                         priv->playlist.cur = total - 1;
327                 break;
328         case REPEAT_NONE:
329                 if (priv->playlist.cur != 0)
330                         priv->playlist.cur--;
331                 break;
332         case REPEAT_ONE:
333                 break;
334         default:
335                 _ERR("Unknown repeat state");
336                 break;
337         }
338
339         _mplayer_show(priv);
340
341         return true;
342 }
343
344 static bool _mplayer_next(struct _priv *priv)
345 {
346         int total;
347         bool r;
348
349         total = eina_list_count(priv->playlist.list);
350
351         r = true;
352
353         switch (priv->playlist.repeat) {
354         case REPEAT_ALL:
355                 if (priv->playlist.cur != total - 1)
356                         priv->playlist.cur++;
357                 else
358                         priv->playlist.cur = 0;
359                 break;
360         case REPEAT_NONE:
361                 if (priv->playlist.cur != total - 1)
362                         priv->playlist.cur++;
363                 else {
364                         priv->playlist.cur = 0;
365                         r = false;
366                 }
367                 break;
368         case REPEAT_ONE:
369                 break;
370         default:
371                 _ERR("Unknown repeat state");
372                 break;
373         }
374
375         _mplayer_show(priv);
376
377         return r;
378 }
379
380 static void _mplayer_set_current(struct _priv *priv, int index)
381 {
382         int total;
383
384         if (index < 0)
385                 return;
386
387         total = eina_list_count(priv->playlist.list);
388
389         if (index >= total)
390                 return;
391
392         priv->playlist.cur = index;
393
394         _mplayer_show(priv);
395 }
396
397 static int _player_get_position(void *data)
398 {
399         struct _priv *priv;
400
401         if (!data)
402                 return 0;
403
404         priv = data;
405
406         return playermgr_get_position(priv->player);
407 }
408
409 static void _player_play_pause(struct _priv *priv)
410 {
411         app_media_info *mi;
412         player_state_e state;
413
414         playermgr_get_state(priv->player, &state);
415
416         switch (state) {
417         case PLAYER_STATE_PAUSED:
418                 progressbar_resume(priv->progress);
419                 playermgr_resume(priv->player);
420                 break;
421         case PLAYER_STATE_PLAYING:
422                 progressbar_pause(priv->progress);
423                 playermgr_pause(priv->player);
424                 break;
425         case PLAYER_STATE_IDLE:
426         case PLAYER_STATE_READY:
427                 mi = _playlist_get_current_media_info(priv);
428                 if (!mi) {
429                         _ERR("failed to getting media info");
430                         return;
431                 }
432
433                 progressbar_start(priv->progress);
434                 playermgr_play(priv->player, mi->file_path, 0);
435                 break;
436         default:
437                 _ERR("player was not created");
438                 break;
439         }
440 }
441
442 static void _player_next(struct _priv *priv)
443 {
444         app_media_info *mi;
445         player_state_e state;
446
447         playermgr_get_state(priv->player, &state);
448
449         switch (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);
455                 break;
456         case PLAYER_STATE_PLAYING:
457                 mi = _playlist_get_current_media_info(priv);
458                 if (!mi) {
459                         _ERR("failed to getting media info");
460                         return;
461                 }
462
463                 progressbar_start(priv->progress);
464                 playermgr_play(priv->player, mi->file_path, 0);
465                 break;
466         default:
467                 _ERR("player was not created");
468                 break;
469         }
470 }
471
472 static void _player_pause(struct _priv *priv)
473 {
474         player_state_e state;
475         struct controller *ctl;
476
477         playermgr_get_state(priv->player, &state);
478
479         switch (state) {
480         case PLAYER_STATE_PLAYING:
481                 progressbar_pause(priv->progress);
482                 playermgr_pause(priv->player);
483                 break;
484         case PLAYER_STATE_PAUSED:
485         case PLAYER_STATE_IDLE:
486         case PLAYER_STATE_READY:
487                 break;
488         default:
489                 _ERR("player was not created");
490                 break;
491         }
492
493         ctl = priv->ctl;
494         ctl->ops->signal(ctl->handle, PLAY_BTN_LOC, SIG_SET_PLAY);
495 }
496
497 static void _player_play(struct _priv *priv)
498 {
499         app_media_info *mi;
500         player_state_e state;
501         const char *path;
502         struct controller *ctl;
503
504         mi = _playlist_get_current_media_info(priv);
505         if (!mi) {
506                 _ERR("failed to getting media info");
507                 return;
508         }
509
510         playermgr_get_state(priv->player, &state);
511
512         switch (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);
517                 break;
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);
522                 else
523                         playermgr_play(priv->player, mi->file_path, 0);
524
525                 progressbar_resume(priv->progress);
526                 break;
527         case PLAYER_STATE_PLAYING:
528                 path = playermgr_get_path(priv->player);
529                 if (path && !strcmp(mi->file_path, path))
530                         break;
531
532                 progressbar_start(priv->progress);
533                 playermgr_play(priv->player, mi->file_path, 0);
534                 break;
535         default:
536                 _ERR("player was not created");
537                 break;
538         }
539
540         ctl = priv->ctl;
541         ctl->ops->signal(ctl->handle, PLAY_BTN_LOC, SIG_SET_PAUSE);
542 }
543
544 static void _player_stop(struct _priv *priv)
545 {
546         struct controller *ctl;
547
548         progressbar_stop(priv->progress);
549         playermgr_stop(priv->player);
550
551         ctl = priv->ctl;
552         ctl->ops->signal(ctl->handle, PLAY_BTN_LOC, SIG_SET_PLAY);
553 }
554
555 static void _player_complete_cb(void *data)
556 {
557         struct _priv *priv;
558         bool r;
559
560         if (!data)
561                 return;
562
563         priv = data;
564
565         r = _mplayer_next(priv);
566         if (r)
567                 _player_next(priv);
568         else
569                 _player_stop(priv);
570 }
571
572 static struct progressbar_ops _progressbar_ops = {
573         .get_value = _player_get_position,
574 };
575
576 static void _pop_view(struct _priv *priv)
577 {
578         struct view_update_data vdata;
579
580         if (viewmgr_active_view_count() > 1) {
581                 vdata.index = _playlist_get_index(priv->playlist.list_org,
582                                 priv->playlist.list, priv->playlist.cur);
583
584                 viewmgr_update_view(VIEW_BASE, UPDATE_FOCUS, &vdata);
585         }
586
587         viewmgr_pop_view();
588
589         if (viewmgr_active_view_count() == 0)
590                 ui_app_exit();
591 }
592
593 static void _key_down(int id, void *data, Evas *e, Evas_Object *obj,
594                         Evas_Event_Key_Down *ev)
595 {
596         struct _priv *priv;
597         bool r;
598
599         if (!data || !ev)
600                 return;
601
602         priv = data;
603
604         if (!strcmp(ev->keyname, KEY_BACK) ||
605                         !strcmp(ev->keyname, KEY_BACK_REMOTE)) {
606                 _pop_view(priv);
607         } else if (!strcmp(ev->keyname, KEY_PLAY)) {
608                 _player_play(priv);
609         } else if (!strcmp(ev->keyname, KEY_PAUSE)) {
610                 _player_pause(priv);
611         } else if (!strcmp(ev->keyname, KEY_STOP)) {
612                 _player_stop(priv);
613         } else if (!strcmp(ev->keyname, KEY_NEXT)) {
614                 r = _mplayer_next(priv);
615                 if (r)
616                         _player_next(priv);
617                 else
618                         _player_stop(priv);
619         } else if (!strcmp(ev->keyname, KEY_PREVIOUS)) {
620                 _mplayer_prev(priv);
621                 _player_next(priv);
622         }
623 }
624
625 static void _list_set_focus(struct _priv *priv)
626 {
627         struct _list_data *ld;
628
629         ld = eina_list_nth(priv->item_list, priv->playlist.cur);
630         if (!ld) {
631                 _ERR("failed to get list data");
632                 return;
633         }
634
635         elm_object_item_focus_set(ld->item, EINA_TRUE);
636 }
637
638 static void _list_free(struct _priv *priv)
639 {
640         elm_genlist_clear(priv->list);
641
642         eina_list_free(priv->item_list);
643         priv->item_list = NULL;
644 }
645
646 static void _list_item_del(void *data, Evas_Object *obj)
647 {
648         free(data);
649 }
650
651 static char *_list_text_get(void *data, Evas_Object *obj, const char *part)
652 {
653         struct _list_data *ld;
654         app_media_info *mi;
655         int index;
656         char buf[1024];
657
658         if (!data)
659                 return NULL;
660
661         ld = data;
662         index = elm_genlist_item_index_get(ld->item);
663
664         mi = app_media_get_info(ld->am);
665         if (!mi) {
666                 _ERR("failed to get media info");
667                 return NULL;
668         }
669
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);
678         } else {
679                 return NULL;
680         }
681
682         return strdup(buf);
683 }
684
685 static Evas_Object *_list_content_get(void *data,
686                         Evas_Object *obj, const char *part)
687 {
688         struct _list_data *ld;
689         app_media_info *mi;
690         Evas_Object *image;
691
692         if (!data)
693                 return NULL;
694
695         ld = data;
696
697         mi = app_media_get_info(ld->am);
698         if (!mi) {
699                 _ERR("failed to get media info");
700                 return NULL;
701         }
702
703         image = NULL;
704         if (!strcmp(part, PART_ELM_SWALLOW_FAVORITE)) {
705                 if (!mi->favorite)
706                         return NULL;
707
708                 image = util_add_image(obj, IMAGE_MUSIC_LIST_FAVORITE);
709                 if (!image) {
710                         _ERR("failed to create image object");
711                         return NULL;
712                 }
713
714                 evas_object_show(image);
715         }
716
717         return image;
718 }
719
720 static void _list_selected(int id, void *data,
721                 Evas_Object *obj, Elm_Object_Item *it)
722 {
723         struct _priv *priv;
724         int index;
725
726         if (!data || !it)
727                 return;
728
729         priv = data;
730         index = elm_genlist_item_index_get(it) - 1;
731
732         if (priv->playlist.cur != index)
733                 _mplayer_set_current(priv, index);
734
735         _player_play(priv);
736 }
737
738 static void _list_realized(int id, void *data,
739                 Evas_Object *obj, Elm_Object_Item *it)
740 {
741         struct _priv *priv;
742         int index;
743
744         if (!data || !it)
745                 return;
746
747         priv = data;
748         index = elm_genlist_item_index_get(it) - 1;
749
750         if (priv->playlist.cur == index) {
751                 elm_object_item_signal_emit(it,
752                                 SIG_ITEM_SELECTED, SIG_SOURCE_SRC);
753         } else {
754                 elm_object_item_signal_emit(it,
755                                 SIG_ITEM_UNSELECTED, SIG_SOURCE_SRC);
756         }
757 }
758
759 static void _list_unrealized(int id, void *data,
760                 Evas_Object *obj, Elm_Object_Item *it)
761 {
762         if (!it)
763                 return;
764
765         elm_object_item_signal_emit(it, SIG_ELM_UNFOCUSED, SIG_SOURCE_ELM);
766 }
767
768 static void _list_mouse_move(int id, void *data, Evas *e, Evas_Object *obj,
769                         Evas_Event_Mouse_Move *ev)
770 {
771         Elm_Object_Item *it;
772
773         if (!data || !ev)
774                 return;
775
776         it = elm_genlist_at_xy_item_get(obj, ev->cur.canvas.x,
777                         ev->cur.canvas.y, NULL);
778
779         if (!it)
780                 return;
781
782         if (!elm_object_item_focus_get(it))
783                 elm_object_item_focus_set(it, EINA_TRUE);
784 }
785
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,
792 };
793
794 static input_handler _btn_handler = {
795         .key_down = _key_down,
796 };
797
798 static void _add_playlist_item(struct _priv *priv)
799 {
800         Elm_Genlist_Item_Class *ic;
801         Elm_Object_Item *item;
802         app_media *am;
803         int i;
804         int total;
805
806         _list_free(priv);
807
808         ic = elm_genlist_item_class_new();
809         if (!ic) {
810                 _ERR("failed to get genlist item class");
811                 return;
812         }
813
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;
819
820         total = eina_list_count(priv->playlist.list);
821
822         for (i = 0; i < total; i++) {
823                 struct _list_data *ld;
824
825                 ld = calloc(1, sizeof(*ld));
826                 if (!ld)
827                         continue;
828
829                 am = eina_list_nth(priv->playlist.list, i);
830                 ld->am = am;
831
832                 item = elm_genlist_item_append(priv->list, ic, ld, NULL,
833                                 ELM_GENLIST_ITEM_NONE, NULL, NULL);
834                 ld->item = item;
835
836                 priv->item_list = eina_list_append(priv->item_list, ld);
837         }
838 }
839
840 static void _callback_music(void *data, const char *ev)
841 {
842         struct _priv *priv;
843         bool r;
844
845         if (!data || !ev)
846                 return;
847
848         priv = data;
849
850         if (!strcmp(ev, SRC_BTN_MUSIC_PREV)) {
851                 _mplayer_prev(priv);
852                 _player_next(priv);
853         } else if (!strcmp(ev, SRC_BTN_MUSIC_NEXT)) {
854                 r = _mplayer_next(priv);
855                 if (r)
856                         _player_next(priv);
857                 else
858                         _player_stop(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,
863                                 priv->playlist.cur);
864                 _add_playlist_item(priv);
865
866                 _mplayer_set_current(priv, priv->playlist.cur);
867                 _player_play(priv);
868         } else if (!strcmp(ev, SRC_BTN_MUSIC_REPEAT)) {
869                 _playlist_set_repeat_mode(priv);
870         }
871 }
872
873 static bool _ui_init(struct _priv *priv)
874 {
875         struct controller *ctl;
876         struct progressbar *prog;
877         Evas_Object *obj;
878         int i;
879
880         obj = elm_image_add(priv->base);
881         if (!obj) {
882                 _ERR("failed to adding image");
883                 return false;
884         }
885
886         priv->thumb = obj;
887
888         ctl = controller_create(priv->base);
889         if (!ctl) {
890                 _ERR("failed to create controller");
891                 return false;
892         }
893
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);
898
899                 obj = ctl->ops->get_object(ctl->handle, i);
900                 if (obj)
901                         inputmgr_add_callback(obj, 0, &_btn_handler, priv);
902         }
903
904         ctl->ops->add_callback(ctl->handle, _callback_music, priv);
905
906         priv->ctl = ctl;
907
908         prog = progressbar_create(priv->base, STYLE_MPLAYER_PROGRESS);
909         if (!prog) {
910                 _ERR("failed to adding progressbar");
911                 goto err;
912         }
913
914         progressbar_set_parts(prog, PART_MPLAYER_SLIDER, PART_MPLAYER_TOTAL,
915                         PART_MPLAYER_PROGRESS, "");
916         progressbar_set_ops(prog, &_progressbar_ops, priv);
917
918         priv->progress = prog;
919
920         obj = util_add_genlist(priv->base);
921         if (!obj)
922                 goto err;
923
924         elm_object_part_content_set(priv->base, PART_MPLAYER_LIST, obj);
925         inputmgr_add_callback(obj, 0, &_list_handler, priv);
926
927         priv->list = obj;
928
929         return true;
930
931 err:
932         controller_destroy(ctl);
933         return false;
934 }
935
936 static Evas_Object *_create(Evas_Object *win, void *data)
937 {
938         struct _priv *priv;
939         Evas_Object *base;
940         struct playermgr *player;
941         bool r;
942
943         if (!win) {
944                 _ERR("failed to get win object");
945                 return NULL;
946         }
947
948         priv = calloc(1, sizeof(*priv));
949         if (!priv) {
950                 _ERR("failed to allocate priv");
951                 return NULL;
952         }
953
954         base = elm_layout_add(win);
955         if (!base) {
956                 _ERR("failed to create base object");
957                 goto err;
958         }
959
960         elm_layout_file_set(base, EDJEFILE, GRP_MPLAYER_VIEW);
961
962         evas_object_size_hint_weight_set(base,
963                         EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
964         elm_win_resize_object_add(win, base);
965
966         priv->win = win;
967         priv->base = base;
968
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;
974
975         player = playermgr_create(NULL);
976         if (!player) {
977                 _ERR("failed to create player");
978                 goto err;
979         }
980
981         r = playermgr_set_completed_cb(player, _player_complete_cb, priv);
982         if (!r) {
983                 _ERR("failed to set callback");
984                 playermgr_destroy(player);
985                 goto err;
986         }
987
988         priv->player = player;
989
990         r = _ui_init(priv);
991         if (!r) {
992                 _ERR("failed to init UI");
993                 playermgr_destroy(player);
994                 goto err;
995         }
996
997         viewmgr_set_view_data(VIEW_MPLAYER, priv);
998
999         return base;
1000
1001 err:
1002         free(priv);
1003         return NULL;
1004 }
1005
1006 static void _show(void *view_data)
1007 {
1008         struct _priv *priv;
1009
1010         if (!view_data) {
1011                 _ERR("failed to get view data");
1012                 return;
1013         }
1014
1015         priv = view_data;
1016
1017         media_content_connect();
1018
1019         _mplayer_show(priv);
1020
1021         _list_set_focus(priv);
1022         _player_play(priv);
1023
1024         evas_object_show(priv->base);
1025 }
1026
1027 static void _hide(void *view_data)
1028 {
1029         struct _priv *priv;
1030
1031         if (!view_data) {
1032                 _ERR("failed to get view data");
1033                 return;
1034         }
1035
1036         priv = view_data;
1037
1038         _mplayer_hide(priv);
1039
1040         media_content_disconnect();
1041
1042         evas_object_hide(priv->base);
1043 }
1044
1045 static void _update(void *view_data, int update_type, void *data)
1046 {
1047         struct _priv *priv;
1048         struct view_update_data *vdata;
1049
1050         if (!view_data) {
1051                 _ERR("failed to get view data");
1052                 return;
1053         }
1054
1055         priv = view_data;
1056         vdata = data;
1057
1058         switch (update_type) {
1059         case UPDATE_CONTENT:
1060                 if (!vdata)
1061                         break;
1062
1063                 if (priv->playlist.list_org != vdata->list) {
1064                         priv->playlist.list_org = vdata->list;
1065                         priv->playlist.list = eina_list_clone(vdata->list);
1066
1067                         _playlist_set_list(priv,
1068                                         priv->playlist.shuffle, vdata->index);
1069                 } else {
1070                         priv->playlist.cur = _playlist_get_index(
1071                                         priv->playlist.list,
1072                                         vdata->list, vdata->index);
1073                 }
1074
1075                 _add_playlist_item(priv);
1076                 break;
1077         case UPDATE_PLAYER:
1078                 _player_stop(priv);
1079                 break;
1080         default:
1081                 break;
1082         }
1083 }
1084
1085 static void _pause(void *view_data)
1086 {
1087         struct _priv *priv;
1088
1089         if (!view_data) {
1090                 _ERR("failed to get view data");
1091                 return;
1092         }
1093
1094         priv = view_data;
1095
1096         _player_stop(priv);
1097 }
1098
1099 static void _destroy(void *view_data)
1100 {
1101         struct _priv *priv;
1102         struct controller *ctl;
1103         Evas_Object *obj;
1104         int i;
1105
1106         if (!view_data) {
1107                 _ERR("failed to get view data");
1108                 return;
1109         }
1110
1111         priv = view_data;
1112
1113         ctl = priv->ctl;
1114
1115         for (i = 0; i < ARRAY_SIZE(btn_player); i++) {
1116                 obj = ctl->ops->get_object(ctl->handle, i);
1117                 if (obj)
1118                         inputmgr_remove_callback(obj, &_btn_handler);
1119         }
1120
1121         eina_list_free(priv->playlist.list);
1122
1123         _list_free(priv);
1124         inputmgr_remove_callback(priv->list, &_list_handler);
1125
1126         _player_stop(priv);
1127         playermgr_destroy(priv->player);
1128
1129         controller_destroy(priv->ctl);
1130         progressbar_destroy(priv->progress);
1131
1132         evas_object_del(priv->base);
1133
1134         free(priv);
1135 }
1136
1137 static view_class _vclass = {
1138         .view_id = VIEW_MPLAYER,
1139         .create = _create,
1140         .show = _show,
1141         .hide = _hide,
1142         .update = _update,
1143         .pause = _pause,
1144         .destroy = _destroy,
1145 };
1146
1147 view_class *view_mplayer_get_vclass(void)
1148 {
1149         return &_vclass;
1150 }