Modification due to the change of CBaseView
[profile/tv/apps/native/musicplayer.git] / src / views / playback-view.cpp
1 /*
2  * Copyright (c) 2014 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 <AppCommon.h>
18 #include "i18n.h"
19 #include "define.h"
20 #include "common.h"
21 #include "Timer.h"
22 #include "song_info.h"
23 #include "album_info.h"
24 #include "music-controller.h"
25 #include "volume-control.h"
26 #include "common-ui.h"
27 #include "playback-view.h"
28 #include "context-view.h"
29 #include "HandleVolume.h"
30 #include "PlaySettingCtxPopup.h"
31 #include "Info.h"
32 #include "SliderWidget.h"
33 #include "PlaybackController.h"
34 #include "AlbumCover.h"
35 #include "SongTitleLabel.h"
36
37
38 #define TOTAL_CONTROL_BTNS 6
39 #define TOTAL_EDIT_BTNS    3
40
41
42 enum EEvasObject {
43         EO_BASE,
44         EO_PLAYLIST,
45 };
46
47 struct SItemInfo {
48         Elm_Object_Item *item;
49         CSongInfo *sinfo;
50         bool edit_mode;
51         bool check_status;
52         bool select_status;
53 };
54
55 struct SPlaybackView {
56         Evas_Object *eoWin;
57         Evas_Object *eoPlaylist;
58
59         Elm_Object_Item *focused_item;
60
61         CPlaybackController *pPlaybackController;
62         // These are reference values.
63         Evas_Object *eoBtnControl[TOTAL_CONTROL_BTNS];
64         Evas_Object *eoBtnEdit[TOTAL_EDIT_BTNS];
65
66         CAlbumCover *pAlbumCover;
67         CSliderWidget *pSliderWidget;
68         CSongTitleLabel *pSongTitleLabel;
69
70         Eina_List *elInfo;
71         CMusicController *pController; //! NOT NULL
72         CSongInfo *csinfo;
73         CViewMgr *mgr;
74         SItemInfo *cs_itinfo;
75         SContentInfo *ctxtinfo;
76
77         CHandleVolume *pHandleVolume;
78
79         int numCheckedItem;
80
81         SPlaybackView() {
82                 memset(this, 0, sizeof(SPlaybackView));
83         }
84 };
85
86
87 void CPlaybackView::sm_CbCtxtUpdate(void *dt, enum EActionType type, int lid)
88 {
89         CPlaybackView *root = (CPlaybackView *)dt;
90         if (root)
91                 root->m_OnCtxtUpdate(type, lid);
92 }
93
94
95 void CPlaybackView::m_OnCtxtUpdate(EActionType type, int lid)
96 {
97         SItemInfo *itinfo = NULL;
98         Elm_Object_Item *focusedItem = NULL;
99
100         if (!m->ctxtinfo || !m->ctxtinfo->context)
101                 return;
102
103         itinfo = m_FindItemInfoFromSong(m->elInfo,
104                 (CSongInfo *)m->ctxtinfo->context);
105         if (!itinfo) {
106                 _ERR(" Unable to find song in the list ");
107                 return;
108         }
109
110         if (type == ACTION_TYPE_DELETE) {
111                 itinfo->check_status = true;
112                 m_DeleteSelectedItems();
113
114                 if (!m->mgr->PopView()) {
115                         _ERR("CViewMgr::PopView failed");
116                         return;
117                 }
118
119                 SParcel parcel;
120                 memset(&parcel, 0, sizeof(SParcel));
121                 parcel.updateType = E_PLAYLIST_UPDATE;
122                 t_OnUpdate(&parcel);
123
124                 focusedItem = m->cs_itinfo->item;
125         }
126         else { // ACTION_TYPE_PLAY
127                 if (m->ctxtinfo->status == PLAY_STATUS_PLAY)
128                         m_KeyPausePress();
129                 else {
130                         if (itinfo == m->cs_itinfo)
131                                 m_KeyPlayPress();
132                         else
133                                 m_HandleGenlistItemActivated(m->eoPlaylist, itinfo->item);
134                 }
135
136                 if (!m->mgr->PopView()) {
137                         _ERR("CViewMgr::PopView failed");
138                         return;
139                 }
140
141                 focusedItem = m->focused_item;
142         }
143
144         if (!CViewMgr::GetInstance()->HideView(MUSIC_BASE_VIEW))
145                 _ERR("CViewMgr::HideView failed");
146
147         t_OnShow();
148
149         if (focusedItem) {
150                 elm_genlist_item_show(focusedItem, ELM_GENLIST_ITEM_SCROLLTO_IN);
151                 elm_object_item_focus_set(focusedItem, EINA_TRUE);
152         }
153 }
154
155
156 void CPlaybackView::sm_CbCtxtClose(void *dt)
157 {
158         CPlaybackView *root = (CPlaybackView *)dt;
159         if (root)
160                 root->m_OnCtxtClose();
161 }
162
163
164 void CPlaybackView::m_OnCtxtClose(void)
165 {
166         if (!m->mgr->PopView()) {
167                 _ERR("CViewMgr::PopView failed");
168                 return;
169         }
170
171         elm_object_item_focus_set(m->focused_item, EINA_TRUE);
172 }
173
174
175 int CPlaybackView::sm_CbCurrentSongCount(void *cookie)
176 {
177         CPlaybackView *root = (CPlaybackView *)cookie;
178         int ret = 0;
179         if (root)
180                 ret = root->m_CbCurrentSongCount();
181
182         return ret;
183 }
184
185
186 int CPlaybackView::m_CbCurrentSongCount(void)
187 {
188         return eina_list_count(m->elInfo);
189 }
190
191
192 void CPlaybackView::m_ChangeEditmodeAll(Eina_List *list, bool flag)
193 {
194         SItemInfo *itinfo = NULL;
195         void *obj = NULL;
196         Eina_List *l = NULL;
197
198         EINA_LIST_FOREACH(list, l, obj) {
199                 itinfo = (SItemInfo *)obj;
200                 itinfo->edit_mode = flag;
201         }
202 }
203
204
205 void CPlaybackView::m_DisableCheckAll(Eina_List *list)
206 {
207         SItemInfo *itinfo = NULL;
208         void *obj = NULL;
209         Eina_List *l = NULL;
210
211         EINA_LIST_FOREACH(list, l, obj) {
212                 itinfo = (SItemInfo *)obj;
213                 itinfo->check_status = false;
214         }
215
216         m->numCheckedItem = 0;
217 }
218
219
220 void CPlaybackView::m_SelectItem(SItemInfo *pItemInfo)
221 {
222         if (!pItemInfo || !pItemInfo->item)
223                 return;
224
225         elm_genlist_item_bring_in(pItemInfo->item, ELM_GENLIST_ITEM_SCROLLTO_IN);
226         elm_object_item_signal_emit(pItemInfo->item, MUSIC_SIGNAL_SELECT_ITEM, MUSIC_PLAYBACK_VIEW);
227
228         pItemInfo->select_status = true;
229 }
230
231
232 void CPlaybackView::m_UnselectItem(SItemInfo *pItemInfo)
233 {
234         if (!pItemInfo || !pItemInfo->item)
235                 return;
236
237         elm_object_item_signal_emit(pItemInfo->item, MUSIC_SIGNAL_UNSELECT_ITEM,
238                 MUSIC_PLAYBACK_VIEW);
239
240         pItemInfo->select_status = false;
241 }
242
243
244 void CPlaybackView::m_UpdateEmptySongInfo(void)
245 {
246         m->pController->SetPlayState(PLAY_STATUS_INITIAL);
247 }
248
249
250 void CPlaybackView::m_UpdateCtxtView(int playStatus)
251 {
252         if (!m->cs_itinfo || !m->ctxtinfo)
253                 return;
254
255         if (!m->mgr->CheckTop(MUSIC_CONTEXT_VIEW))
256                 return;
257
258         if (m->cs_itinfo->sinfo == m->ctxtinfo->context) {
259                 m->ctxtinfo->status = (EPlayStatus)playStatus;
260
261                 SParcel parcel;
262                 memset(&parcel, 0, sizeof(SParcel));
263                 parcel.updateType = E_SONG_UPDATE;
264                 m->mgr->UpdateView((const char *)MUSIC_CONTEXT_VIEW, &parcel);
265         }
266 }
267
268
269 void CPlaybackView::m_UpdateCurrentSongItem(int index)
270 {
271         SItemInfo *pItemInfo = NULL;
272
273         if (m->cs_itinfo) {
274                 m_UnselectItem(m->cs_itinfo);
275                 m_UpdateCtxtView(PLAY_STATUS_PAUSE);
276         }
277
278         pItemInfo = (SItemInfo *)eina_list_nth(m->elInfo, index);
279
280         if (pItemInfo) {
281                 m->cs_itinfo = pItemInfo;
282                 if (m->pController->PlayState() == PLAY_STATUS_STOP) {
283                         elm_genlist_item_bring_in(pItemInfo->item,
284                                 ELM_GENLIST_ITEM_SCROLLTO_IN);
285                 }
286                 else {
287                         m_SelectItem(pItemInfo);
288                         m_UpdateCtxtView(PLAY_STATUS_PLAY);
289                 }
290         }
291 }
292
293
294 void CPlaybackView::m_UpdateEditmodeFocusSequence(void)
295 {
296         elm_object_focus_next_object_set(m->eoPlaylist, m->eoBtnEdit[EDIT_BTN_CANCEL], ELM_FOCUS_LEFT);
297         elm_object_focus_next_object_set(m->eoBtnEdit[EDIT_BTN_CANCEL], m->eoPlaylist, ELM_FOCUS_RIGHT);
298         elm_object_focus_next_object_set(m->pSliderWidget->Base(), m->eoBtnEdit[EDIT_BTN_CANCEL], ELM_FOCUS_DOWN);
299 }
300
301
302 void CPlaybackView::m_UpdatePlaymodeFocusSequence(void)
303 {
304         switch (m->pController->PlayState()) {
305         case PLAY_STATUS_INITIAL:
306                 // Do nothing
307                 break;
308
309         case PLAY_STATUS_STOP:
310                 elm_object_focus_next_object_set(m->eoPlaylist, m->eoBtnControl[CTRL_BTN_PLAY], ELM_FOCUS_LEFT);
311                 elm_object_focus_next_object_set(m->eoBtnControl[CTRL_BTN_PLAY], m->eoPlaylist, ELM_FOCUS_RIGHT);
312                 elm_object_focus_next_object_set(m->eoBtnControl[CTRL_BTN_PLAY], m->eoBtnControl[CTRL_BTN_REPEAT], ELM_FOCUS_LEFT);
313                 elm_object_focus_next_object_set(m->eoBtnControl[CTRL_BTN_REPEAT], m->eoBtnControl[CTRL_BTN_PLAY], ELM_FOCUS_RIGHT);
314                 elm_object_signal_emit(m->eoBtnControl[CTRL_BTN_PLAY], MUSIC_SIGNAL_PAUSE, MUSIC_PLAYBACK_VIEW);
315                 break;
316
317         case PLAY_STATUS_PLAY:
318         case PLAY_STATUS_PAUSE:
319                 elm_object_focus_next_object_set(m->eoPlaylist,
320                         m->eoBtnControl[CTRL_BTN_FORWARD], ELM_FOCUS_LEFT);
321                 elm_object_focus_next_object_set(m->eoBtnControl[CTRL_BTN_FORWARD],
322                         m->eoPlaylist, ELM_FOCUS_RIGHT);
323                 elm_object_focus_next_object_set(m->eoBtnControl[CTRL_BTN_PLAY],
324                         m->eoBtnControl[CTRL_BTN_FORWARD], ELM_FOCUS_RIGHT);
325                 elm_object_focus_next_object_set(m->eoBtnControl[CTRL_BTN_PLAY],
326                         m->eoBtnControl[CTRL_BTN_REWIND], ELM_FOCUS_LEFT);
327                 elm_object_focus_next_object_set(m->eoBtnControl[CTRL_BTN_REPEAT],
328                         m->eoBtnControl[CTRL_BTN_REWIND], ELM_FOCUS_RIGHT);
329                 break;
330
331         default:
332                 ASSERT(!"Invalid State");
333                 break;
334         }
335 }
336
337
338 void CPlaybackView::m_UpdateCurrentSongInfo(void)
339 {
340         CSongInfo *sinfo = NULL;
341         int index;
342
343         if (eina_list_count(m->elInfo) == 0) {
344                 m->pController->EmptyPlaylist();
345                 return;
346         }
347
348         if (!m->pController->GetCurrentSongIndex(&index)) {
349                 _ERR(" music get current song index failed ");
350                 return;
351         }
352
353         if (!m->pController->GetSonginfoFromIndex(index, &sinfo)) {
354                 _ERR(" music get songinfo failed ");
355                 return;
356         }
357         m->csinfo = sinfo;
358
359         m_UpdateCurrentSongItem(index);
360         m->pController->UpdatePlayerUI();
361         m_UpdatePlaymodeFocusSequence();
362 }
363
364
365 void CPlaybackView::m_DisableEditButtons(bool flag)
366 {
367         /* flag - 1 means disable edit buttons and 0 means enable */
368         if (flag)
369                 elm_object_focus_set(m->eoBtnEdit[EDIT_BTN_CANCEL], EINA_TRUE);
370
371         elm_object_disabled_set(m->eoBtnEdit[EDIT_BTN_DELETE], (Eina_Bool)flag);
372         elm_object_disabled_set(m->eoBtnEdit[EDIT_BTN_DESELECT], (Eina_Bool)flag);
373         if (flag) {
374                 m_UpdateEditmodeFocusSequence();
375                 elm_object_focus_set(m->eoBtnEdit[EDIT_BTN_CANCEL], EINA_TRUE);
376         }
377         else {
378                 elm_object_focus_next_object_set(m->eoBtnEdit[EDIT_BTN_CANCEL], m->eoBtnEdit[EDIT_BTN_DESELECT], ELM_FOCUS_RIGHT);
379                 elm_object_focus_next_object_set(m->eoBtnEdit[EDIT_BTN_DELETE], m->eoPlaylist, ELM_FOCUS_RIGHT);
380                 elm_object_focus_next_object_set(m->eoPlaylist, m->eoBtnEdit[EDIT_BTN_DELETE], ELM_FOCUS_LEFT);
381         }
382 }
383
384
385 void CPlaybackView::m_FromEditToPlaybackMode(void)
386 {
387         if (m->pController->PlayState() == PLAY_STATUS_STOP) {
388                 elm_genlist_item_bring_in(m->cs_itinfo->item,
389                         ELM_GENLIST_ITEM_SCROLLTO_IN);
390         }
391         else
392                 m_SelectItem(m->cs_itinfo);
393
394         elm_object_signal_emit(Base(), MUSIC_SIGNAL_PLAYBACK_MODE,
395                 MUSIC_PLAYBACK_VIEW);
396         elm_object_focus_set(m->eoBtnControl[CTRL_BTN_SETTINGS], EINA_TRUE);
397
398         m_ChangeEditmodeAll(m->elInfo, false);
399
400         elm_genlist_realized_items_update(m->eoPlaylist);
401
402         m_UpdatePlaymodeFocusSequence();
403 }
404
405
406 void CPlaybackView::m_FromPlaybackToEditMode(void)
407 {
408         elm_object_signal_emit(Base(), MUSIC_SIGNAL_EDIT_MODE,
409                 MUSIC_PLAYBACK_VIEW);
410
411         m_DisableEditButtons(true);
412
413         elm_object_focus_set(m->eoBtnEdit[EDIT_BTN_CANCEL], EINA_TRUE);
414
415         m_ChangeEditmodeAll(m->elInfo, true);
416
417         elm_genlist_realized_items_update(m->eoPlaylist);
418
419         m_UpdateEditmodeFocusSequence();
420 }
421
422
423 void CPlaybackView::m_DeleteSelectedItems(void)
424 {
425         Eina_List *l = NULL, *l_next = NULL;
426         SItemInfo *pItemInfo = NULL;
427         void *obj = NULL;
428         bool updateFlag = false;
429         int index;
430
431         m_DisableEditButtons(true);
432         m->numCheckedItem = 0;
433         EINA_LIST_FOREACH_SAFE(m->elInfo, l, l_next, obj) {
434                 pItemInfo = (SItemInfo *)obj;
435                 if (pItemInfo->check_status) {
436                         if (m->cs_itinfo == pItemInfo) {
437                                 updateFlag = true;
438                                 m_UnselectItem(m->cs_itinfo);
439                                 m->cs_itinfo = NULL;
440                                 m->pController->SetPlayState(PLAY_STATUS_STOP);
441                                 m->pController->Stop();
442                         }
443                         index = elm_genlist_item_index_get(pItemInfo->item);
444                         m->pController->RemoveSong(pItemInfo->sinfo, index);
445
446                         m->elInfo = eina_list_remove(m->elInfo, pItemInfo);
447                         elm_object_item_del(pItemInfo->item);
448                 }
449         }
450
451         if (eina_list_count(m->elInfo) == 0) {
452                 m->pController->EmptyPlaylist();
453                 elm_genlist_realized_items_update(m->eoPlaylist);
454                 elm_object_focus_set(m->eoBtnEdit[EDIT_BTN_CANCEL], EINA_TRUE);
455                 return;
456         }
457
458         if (updateFlag)
459                 m_UpdateCurrentSongInfo();
460
461         elm_genlist_realized_items_update(m->eoPlaylist);
462         elm_object_focus_set(m->eoBtnEdit[EDIT_BTN_CANCEL], EINA_TRUE);
463 }
464
465
466 void CPlaybackView::m_KeyBackPress(void)
467 {
468         t_OnHide();
469
470         if (!CViewMgr::GetInstance()->ShowView(MUSIC_BASE_VIEW))
471                 _ERR("CViewMgr::ShowView failed");
472
473         if (CViewMgr::GetInstance()->CheckTop(MUSIC_CONTEXT_VIEW)) {
474                 if (!CViewMgr::GetInstance()->UpdateView(MUSIC_CONTEXT_VIEW, NULL))
475                         _ERR("CViewMgr::UpdateView failed");
476
477                 if (!CViewMgr::GetInstance()->ShowView(MUSIC_CONTEXT_VIEW))
478                         _ERR("CViewMgr::ShowView failed");
479         }
480 }
481
482
483 void CPlaybackView::m_KeyExitPress(void)
484 {
485         m->pController->Stop();
486         elm_exit();
487 }
488
489
490 void CPlaybackView::m_KeyPlayPress(void)
491 {
492         int state;
493
494         if (elm_object_disabled_get(m->eoBtnControl[CTRL_BTN_PLAY]))
495                 return;
496
497         state = m->pController->PlayState();
498         if (state == PLAY_STATUS_PAUSE) {
499                 m->pController->Resume();
500                 elm_object_signal_emit(m->eoBtnControl[CTRL_BTN_PLAY],
501                         MUSIC_SIGNAL_PLAY, MUSIC_PLAYBACK_VIEW);
502         }
503         else if (state != PLAY_STATUS_PLAY) {
504                 m->pController->Start();
505         }
506 }
507
508
509 void CPlaybackView::m_KeyPausePress(void)
510 {
511         int state;
512
513         if (elm_object_disabled_get(m->eoBtnControl[CTRL_BTN_PLAY]))
514                 return;
515
516         state = m->pController->PlayState();
517         if (state == PLAY_STATUS_PLAY) {
518                 elm_object_signal_emit(m->eoBtnControl[CTRL_BTN_PLAY],
519                         MUSIC_SIGNAL_PAUSE, MUSIC_PLAYBACK_VIEW);
520                 m->pController->Pause();
521         }
522 }
523
524
525 void CPlaybackView::m_KeyNextPress(void)
526 {
527         if (elm_object_disabled_get(m->eoBtnControl[CTRL_BTN_FORWARD]))
528                 return;
529
530         m->pController->HandleRemoteButtons(m->eoBtnControl[CTRL_BTN_FORWARD], EVENT_PRESSED);
531 }
532
533
534 void CPlaybackView::m_KeyPreviousPress(void)
535 {
536         if (elm_object_disabled_get(m->eoBtnControl[CTRL_BTN_REWIND]))
537                 return;
538
539         m->pController->HandleRemoteButtons(m->eoBtnControl[CTRL_BTN_REWIND], EVENT_PRESSED);
540 }
541
542
543 void CPlaybackView::m_KeyNextUnpress(void)
544 {
545         if (elm_object_disabled_get(m->eoBtnControl[CTRL_BTN_FORWARD]))
546                 return;
547
548         m->pController->HandleRemoteButtons(m->eoBtnControl[CTRL_BTN_FORWARD], EVENT_UNPRESSED);
549 }
550
551
552 void CPlaybackView::m_KeyPreviousUnpress(void)
553 {
554         if (elm_object_disabled_get(m->eoBtnControl[CTRL_BTN_REWIND]))
555                 return;
556
557         m->pController->HandleRemoteButtons(m->eoBtnControl[CTRL_BTN_REWIND], EVENT_UNPRESSED);
558 }
559
560
561 void CPlaybackView::m_HandleKeyPress(ESKey skey)
562 {
563         switch (skey) {
564         case SKEY_EXIT:
565                 m_KeyExitPress();
566                 break;
567
568         case SKEY_BACK:
569                 m_KeyBackPress();
570                 break;
571
572         case SKEY_PLAY:
573                 m_KeyPlayPress();
574                 break;
575
576         case SKEY_PAUSE:
577                 m_KeyPausePress();
578                 break;
579
580         case SKEY_NEXT:
581                 m_KeyNextPress();
582                 break;
583
584         case SKEY_PREVIOUS:
585                 m_KeyPreviousPress();
586                 break;
587
588         case SKEY_VOLUME_UP:
589                 m->pHandleVolume->Up();
590                 break;
591
592         case SKEY_VOLUME_DOWN:
593                 m->pHandleVolume->Down();
594                 break;
595
596         case SKEY_MUTE:
597                 m->pHandleVolume->Mute();
598                 break;
599
600         default:
601                 break;
602         }
603 }
604
605
606 void CPlaybackView::m_HandleKeyUnpress(ESKey skey)
607 {
608         switch (skey) {
609         case SKEY_PREVIOUS:
610                 m_KeyPreviousUnpress();
611                 break;
612
613         case SKEY_NEXT:
614                 m_KeyNextUnpress();
615                 break;
616
617         default:
618                 break;
619         }
620 }
621
622
623 void CPlaybackView::m_AddCurrentSonginfo(void)
624 {
625         m->pSongTitleLabel = new CSongTitleLabel;
626         m->pSongTitleLabel->Create(Base());
627
628         m->pAlbumCover = new CAlbumCover;
629         m->pAlbumCover->Create(Base());
630         
631         m->pSliderWidget = new CSliderWidget;
632         m->pSliderWidget->Create(Base());
633 }
634
635
636 SItemInfo *CPlaybackView::m_FindItemInfoFromSong(Eina_List *list, CSongInfo *sinfo)
637 {
638         Eina_List *l = NULL;
639         SItemInfo *itinfo = NULL;
640         void *obj = NULL;
641
642         EINA_LIST_FOREACH(list, l, obj) {
643                 itinfo = (SItemInfo *)obj;
644                 if (itinfo->sinfo == sinfo)
645                         return itinfo;
646         }
647
648         return NULL;
649 }
650
651
652 SItemInfo *CPlaybackView::m_FindItemInfoFromItem(Eina_List *list, Elm_Object_Item *item)
653 {
654         Eina_List *l = NULL;
655         SItemInfo *itinfo = NULL;
656         void *obj = NULL;
657
658         EINA_LIST_FOREACH(list, l, obj) {
659                 itinfo = (SItemInfo *)obj;
660                 if (itinfo->item == item)
661                         return itinfo;
662         }
663
664         return NULL;
665 }
666
667
668 void CPlaybackView::m_UpdateItemCheck(SItemInfo *itinfo)
669 {
670         if (!itinfo) {
671                 _ERR(" No item info to Update check ");
672                 return;
673         }
674
675         if (itinfo->check_status) {
676                 elm_object_item_signal_emit(itinfo->item,
677                         MUSIC_SIGNAL_CHECK_OFF, MUSIC_PLAYBACK_VIEW);
678                 itinfo->check_status = false;
679                 m->numCheckedItem--;
680         }
681         else {
682                 elm_object_item_signal_emit(itinfo->item,
683                         MUSIC_SIGNAL_CHECK_ON, MUSIC_PLAYBACK_VIEW);
684                 itinfo->check_status = true;
685                 m->numCheckedItem++;
686         }
687 }
688
689
690 class CElmGenlistItemClass {
691 public:
692         static char *sm_CbTextGet(void *data, Evas_Object *obj, const char *part)
693         {
694                 CSongInfo *sinfo = NULL;
695                 SItemInfo *pItemInfo = (SItemInfo *)data;
696                 char buf[MAX_LENGTH];
697                 char *timestr = NULL;
698                 int duration;
699                 int index;
700
701                 if (!pItemInfo || !obj)
702                         return NULL;
703
704                 sinfo = pItemInfo->sinfo;
705
706                 snprintf(buf, sizeof(buf), "%s", MUSIC_STR_EMPTY);
707
708                 if (!strcmp(part, "elm.text0")) {
709                         index = elm_genlist_item_index_get(pItemInfo->item);
710                         snprintf(buf, sizeof(buf), "%d", index);
711                 }
712                 else if (!strcmp(part, "elm.text1"))
713                         snprintf(buf, sizeof(buf), "%s", sinfo->Name());
714                 else if (!strcmp(part, "elm.text2"))
715                         snprintf(buf, sizeof(buf), "%s - %s",
716                         sinfo->Artist(),
717                         sinfo->Album());
718                 else if (!strcmp(part, "elm.text3")) {
719                         duration = sinfo->Duration();
720                         timestr = CCommonUI::TimeStrFromMilSeconds(duration);
721                         if (timestr) {
722                                 snprintf(buf, sizeof(buf), "%s", timestr);
723                                 free(timestr);
724                         }
725                 }
726
727                 if (strcmp(buf, MUSIC_STR_EMPTY))
728                         return strdup(buf);
729
730                 return NULL;
731         }
732         static Evas_Object *sm_CbContentGet(void *data, Evas_Object *obj, const char *part)
733         {
734                 CSongInfo *sinfo = NULL;
735                 SItemInfo *pItemInfo = (SItemInfo *)data;
736                 Evas_Object *img = NULL;
737                 char *path = NULL;
738                 char buf[MAX_LENGTH];
739
740                 if (!pItemInfo || !obj)
741                         return NULL;
742
743                 sinfo = pItemInfo->sinfo;
744
745                 img = elm_image_add(obj);
746                 if (!img)
747                         return NULL;
748
749                 elm_image_aspect_fixed_set(img, EINA_FALSE);
750
751                 if (!strcmp(part, "elm.swallow.icon")) {
752                         path = sinfo->ThumbnailPath();
753                         if (path)
754                                 elm_image_file_set(img, path, "NULL");
755                         else {
756                                 snprintf(buf, sizeof(buf), "%s/%s", IMAGEDIR,
757                                         MUSIC_IMAGE_DEFAULT_THUMB_126);
758                                 elm_image_file_set(img, buf, "NULL");
759                         }
760                 }
761
762                 return img;
763
764         }
765         static void         sm_CbDel(void *data, Evas_Object *obj)
766         {
767                 free(data);
768         }
769 };
770
771
772 Elm_Genlist_Item_Class *CPlaybackView::m_GetItemClass(void)
773 {
774         Elm_Genlist_Item_Class *list_item = NULL;
775
776         list_item = elm_genlist_item_class_new();
777         if (!list_item) {
778                 _ERR(" elm_genlist_item_class_new failed ");
779                 return NULL;
780         }
781
782         list_item->item_style       = MUSIC_STYLE_PLAYLIST;
783         list_item->func.text_get    = CElmGenlistItemClass::sm_CbTextGet;
784         list_item->func.content_get = CElmGenlistItemClass::sm_CbContentGet;
785         list_item->func.state_get   = NULL;
786         list_item->func.del         = CElmGenlistItemClass::sm_CbDel;
787
788         return list_item;
789 }
790
791
792 void CPlaybackView::m_AddGenlist(void)
793 {
794         Evas_Object *genlist = NULL;
795
796         genlist = elm_genlist_add(Base());
797         if (!genlist)
798                 return;
799
800         elm_genlist_homogeneous_set(genlist, EINA_TRUE);
801         evas_object_size_hint_weight_set(genlist,
802                 EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
803         elm_object_part_content_set(Base(), MUSIC_PART_PLAYLIST, genlist);
804         elm_genlist_select_mode_set(genlist, ELM_OBJECT_SELECT_MODE_ALWAYS);
805         elm_genlist_multi_select_set(genlist, EINA_FALSE);
806
807         Connect(genlist, EO_PLAYLIST, TYPE_REALIZED | TYPE_MOUSE_MOVE |
808                 TYPE_KEY_DOWN | TYPE_ACTIVATED);
809
810         evas_object_show(genlist);
811         m->eoPlaylist = genlist;
812 }
813
814
815 void CPlaybackView::m_AddPlaylist(void)
816 {
817         Elm_Genlist_Item_Class *list_item = NULL;
818         int ts = 0;
819         int i, index = -1;
820         CSongInfo *sinfo = NULL;
821         Elm_Object_Item *item = NULL;
822         SItemInfo *pItemInfo = NULL;
823
824         m_AddGenlist();
825         if (!m->eoPlaylist)
826                 return;
827
828         list_item = m_GetItemClass();
829         if (!list_item) {
830                 evas_object_del(m->eoPlaylist);
831                 return;
832         }
833
834         if (!m->pController->GetTotalSongs(&ts)) {
835                 _ERR(" music get total songs failed ");
836                 return;
837         }
838
839         if (!m->pController->GetCurrentSongIndex(&index))
840                 _ERR(" music get current song index failed ");
841
842         for (i = 0; i < ts; i++) {
843                 if (!m->pController->GetSonginfoFromIndex(i, &sinfo)) {
844                         _ERR(" music get songinfo failed ");
845                         continue;
846                 }
847                 pItemInfo = (SItemInfo *)calloc(1, sizeof(*pItemInfo));
848                 if (!pItemInfo)
849                         return;
850                 pItemInfo->sinfo = sinfo;
851                 pItemInfo->edit_mode = false;
852                 pItemInfo->check_status = false;
853                 pItemInfo->select_status = false;
854
855                 // event handling will be done in OnActivated function
856                 item = elm_genlist_item_append(m->eoPlaylist, list_item,
857                         pItemInfo, NULL, ELM_GENLIST_ITEM_NONE,
858                         NULL, m);
859                 pItemInfo->item = item;
860
861                 if (i == index) {
862                         pItemInfo->select_status = true;
863                         m->cs_itinfo = pItemInfo;
864                 }
865                 m->elInfo = eina_list_append(m->elInfo, pItemInfo);
866         }
867         m->numCheckedItem = 0;
868 }
869
870
871 void CPlaybackView::m_RemovePlaylist(void)
872 {
873         if (m->eoPlaylist) {
874                 elm_genlist_clear(m->eoPlaylist);
875                 m->eoPlaylist = NULL;
876         }
877
878         if (m->elInfo) {
879                 eina_list_free(m->elInfo);
880                 m->elInfo = NULL;
881         }
882 }
883
884
885 void CPlaybackView::m_HandleGenlistItemActivated(Evas_Object *obj, Elm_Object_Item *genListItem)
886 {
887         int index;
888         SItemInfo *itinfo = NULL;
889
890         if (!obj || !genListItem)
891                 return;
892
893         itinfo = m_FindItemInfoFromItem(m->elInfo, genListItem);
894         if (!itinfo) {
895                 _ERR(" no item info found ");
896                 return;
897         }
898
899         if (itinfo->edit_mode) {
900                 m_UpdateItemCheck(itinfo);
901                 if (m->numCheckedItem > 0)
902                         m_DisableEditButtons(false);
903                 else
904                         m_DisableEditButtons(true);
905                 return;
906         }
907
908         index = elm_genlist_item_index_get(genListItem);
909
910         m->pController->PlayIndexSong(--index);
911 }
912
913
914 bool CPlaybackView::Create(void *data, Evas_Object *eoBase)
915 {
916         ASSERT(!m);
917
918         _CREATE_BEGIN{
919                 CPlaybackController::SCallback cb;
920                 Evas_Object *eoBase;
921
922                 _CHECK(m = new SPlaybackView)
923                 _CHECK(m->mgr = CViewMgr::GetInstance())
924                 _CHECK(m->eoWin = m->mgr->Window())
925                 _CHECK(m->pController = new CMusicController)
926                 _CHECK(m->pController->Create())
927                 _CHECK(eoBase = CCommonUI::AddBase(m->eoWin, MUSIC_PLAYBACK_VIEW))
928                 _CHECK(CBaseView::Create(NULL, eoBase))
929                 _CHECK(CTimer::Create());
930                 _CHECK(m->pController->AddListener(this))
931                 _CHECK(m->pPlaybackController = new CPlaybackController)
932                 _COMMAND{ cb.cookie = this; cb.OnCurrentSongCount = sm_CbCurrentSongCount; }
933                 _CHECK(m->pPlaybackController->Create(eoBase, &cb))
934
935                 _WHEN_SUCCESS{
936                         evas_object_data_set(eoBase, PLAYBACK_VIEW_DATA, m);
937
938                         m_AddCurrentSonginfo();
939                         m_AddPlaylist();
940
941                         int i;
942                         for (i = 0; i < TOTAL_CONTROL_BTNS; i++)
943                                 m->eoBtnControl[i] = m->pPlaybackController->ControlBtnsObject((EPlayerControlBtns)i);
944
945                         for (i = 0; i < TOTAL_EDIT_BTNS; i++)
946                                 m->eoBtnEdit[i] = m->pPlaybackController->EditBtnsObject((EPlayerEditBtns)i);
947
948                         m->pHandleVolume = new CHandleVolume;
949                         m->pHandleVolume->Create(eoBase);
950
951                         m_UpdatePlaymodeFocusSequence();
952
953                         Connect(eoBase, EO_BASE, TYPE_KEY_DOWN | TYPE_KEY_UP);
954                 }
955
956                 _CHECK_FAIL{ m->pPlaybackController->Destroy(); }
957                 _CHECK_FAIL{ delete m->pPlaybackController; }
958                 _CHECK_FAIL{ m->pController->RemoveListener(this); }
959                 _CHECK_FAIL{ CTimer::Destroy(); }
960                 _CHECK_FAIL{ CBaseView::Destroy(); }
961                 _CHECK_FAIL{ evas_object_del(eoBase); }
962                 _CHECK_FAIL{ m->pController->Destroy(); }
963                 _CHECK_FAIL{ delete m->pController; }
964                 _CHECK_FAIL{ /* mgr->Window() */ }
965                 _CHECK_FAIL{ /* CViewerMgr::GetInstance() */}
966                 _CHECK_FAIL{ delete m; m = NULL; }
967         }_CREATE_END_AND_CATCH{ return false; }
968
969         return true;
970 }
971
972
973 void CPlaybackView::Destroy(void)
974 {
975         ASSERT(m);
976
977         Evas_Object *eoBase = Base();
978
979         Disconnect(eoBase);
980
981         m->pPlaybackController->Destroy();
982         delete m->pPlaybackController;
983
984         m->pController->RemoveListener(this);
985
986         m->pSliderWidget->Destroy();
987         delete m->pSliderWidget;
988
989         m->pAlbumCover->Destroy();
990         delete m->pAlbumCover;
991
992         m->pSongTitleLabel->Destroy();
993         delete m->pSongTitleLabel;
994
995         m->pHandleVolume->Destroy();
996         delete m->pHandleVolume;
997         CBaseView::Destroy();
998         evas_object_del(eoBase);
999
1000         free(m->ctxtinfo);
1001         delete m;
1002         m = NULL;
1003 }
1004
1005
1006 void CPlaybackView::t_OnShow(void)
1007 {
1008         ASSERT(m);
1009
1010         int state;
1011
1012         m_UpdateCurrentSongInfo();
1013
1014         state = m->pController->PlayState();
1015         if (state == PLAY_STATUS_INITIAL || state == PLAY_STATUS_STOP) {
1016                 m_RemovePlaylist();
1017                 m_AddPlaylist();
1018                 m->pController->Start();
1019         }
1020
1021         if (m->cs_itinfo) {
1022                 elm_genlist_item_show(m->cs_itinfo->item, ELM_GENLIST_ITEM_SCROLLTO_IN);
1023                 elm_object_item_focus_set(m->cs_itinfo->item, EINA_TRUE);
1024         }
1025
1026         evas_object_show(Base());
1027 }
1028
1029
1030 void CPlaybackView::t_OnUpdate(void *data)
1031 {
1032         ASSERT(m);
1033
1034         SParcel *parcel = (SParcel *)data;
1035         int updateType;
1036         ESKey keyEvent = SKEY_MAX;
1037
1038         if (!parcel)
1039                 updateType = E_PLAYLIST_UPDATE;
1040         else {
1041                 updateType = parcel->updateType;
1042                 keyEvent = parcel->keyEvent;
1043         }
1044
1045         switch (updateType) {
1046         case E_PLAYLIST_UPDATE:
1047                 m_RemovePlaylist();
1048                 m_AddPlaylist();
1049                 elm_object_disabled_set(m->eoBtnControl[CTRL_BTN_FORWARD], EINA_FALSE);
1050                 elm_object_disabled_set(m->eoBtnControl[CTRL_BTN_REWIND], EINA_FALSE);
1051                 elm_object_disabled_set(m->eoBtnControl[CTRL_BTN_PLAY], EINA_FALSE);
1052                 elm_object_focus_next_object_set(m->eoBtnControl[CTRL_BTN_REPEAT],
1053                         m->eoBtnControl[CTRL_BTN_REWIND], ELM_FOCUS_RIGHT);
1054                 m_FromEditToPlaybackMode();
1055                 break;
1056
1057         case E_KEY_PRESS:
1058                 m_HandleKeyPress(keyEvent);
1059                 break;
1060
1061         case E_KEY_RELEASE:
1062                 m_HandleKeyUnpress(keyEvent);
1063                 break;
1064
1065         default:
1066                 break;
1067         }
1068 }
1069
1070
1071 void CPlaybackView::t_OnTimer(int id)
1072 {
1073 }
1074
1075
1076 void CPlaybackView::t_OnHide(void)
1077 {
1078         ASSERT(m);
1079
1080         evas_object_hide(Base());
1081 }
1082
1083
1084 void CPlaybackView::OnSKeyDown(int id, Evas *e, Evas_Object *obj, Evas_Event_SKey_Down *ev)
1085 {
1086         switch (id) {
1087         case EO_BASE:
1088                 m_HandleKeyPress(ev->skey);
1089                 break;
1090
1091         case EO_PLAYLIST:
1092                 {
1093                         Elm_Object_Item *it = NULL;
1094                         it = elm_object_focused_item_get(obj);
1095                         if (!it) {
1096                                 _ERR(" unable to get focused item ");
1097                                 return;
1098                         }
1099                         m->focused_item = it;
1100
1101                         switch (ev->skey) {
1102                         case SKEY_MENU:
1103                                 {
1104                                         SContentInfo *ctxtinfo = NULL;
1105                                         SItemInfo *itinfo = NULL;
1106                                         SParcel parcel;
1107
1108                                         if (m->ctxtinfo) {
1109                                                 free(m->ctxtinfo);
1110                                                 m->ctxtinfo = NULL;
1111                                         }
1112
1113                                         ctxtinfo = (SContentInfo *)calloc(1, sizeof(*ctxtinfo));
1114                                         if (!ctxtinfo)
1115                                                 return;
1116
1117                                         itinfo = m_FindItemInfoFromItem(m->elInfo, it);
1118                                         if (!itinfo) {
1119                                                 free(ctxtinfo);
1120                                                 return;
1121                                         }
1122
1123                                         if (m->pController->PlayState() == PLAY_STATUS_PLAY &&
1124                                                 itinfo == m->cs_itinfo)
1125                                                 ctxtinfo->status = PLAY_STATUS_PLAY;
1126                                         else
1127                                                 ctxtinfo->status = PLAY_STATUS_PAUSE;
1128
1129                                         ctxtinfo->cbdata = this;
1130                                         ctxtinfo->update = sm_CbCtxtUpdate;
1131                                         ctxtinfo->close = sm_CbCtxtClose;
1132                                         ctxtinfo->type = CONTEXT_TYPE_PLAYSONG;
1133                                         ctxtinfo->context = itinfo->sinfo;
1134
1135                                         m->ctxtinfo = ctxtinfo;
1136
1137                                         memset(&parcel, 0, sizeof(SParcel));
1138                                         parcel.ctxtInfo = ctxtinfo;
1139                                         if (!m->mgr->PushView(MUSIC_CONTEXT_VIEW, &parcel))
1140                                                 _ERR("viewmgr push view MUSIC_CONTEXT_VIEW failed");
1141                                 }
1142                                 break;
1143
1144                         default:
1145                                 break;
1146                         }
1147                 }
1148                 break;
1149
1150         default:
1151                 break;
1152         }
1153 }
1154
1155
1156 void CPlaybackView::OnSKeyUp(int id, Evas *e, Evas_Object *obj, Evas_Event_SKey_Up *ev)
1157 {
1158         switch (id) {
1159         case EO_BASE:
1160                 m_HandleKeyUnpress(ev->skey);
1161                 break;
1162
1163         default:
1164                 break;
1165         }
1166 }
1167
1168
1169 void CPlaybackView::OnMouseMove(int id, Evas *e, Evas_Object *obj, Evas_Event_Mouse_Move *ev)
1170 {
1171         switch (id) {
1172         case EO_PLAYLIST:
1173                 {
1174                         Elm_Object_Item *item;
1175
1176                         item = elm_genlist_at_xy_item_get(obj, ev->cur.canvas.x,
1177                                 ev->cur.canvas.y, NULL);
1178                         if (!item)
1179                                 return;
1180
1181                         if (!elm_object_item_focus_get(item))
1182                                 elm_object_item_focus_set(item, EINA_TRUE);
1183                 }
1184                 break;
1185
1186         default:
1187                 break;
1188         }
1189 }
1190
1191
1192 void CPlaybackView::OnRealized(int id, Evas_Object *obj, Elm_Object_Item *item)
1193 {
1194         switch (id) {
1195         case EO_PLAYLIST:
1196                 {
1197                         int index = elm_genlist_item_index_get(item);
1198                         if ((index & 1) == 1)
1199                                 elm_object_item_signal_emit(item,
1200                                         MUSIC_SIGNAL_EVEN_ROW, MUSIC_PLAYBACK_VIEW);
1201                         else
1202                                 elm_object_item_signal_emit(item,
1203                                         MUSIC_SIGNAL_ODD_ROW, MUSIC_PLAYBACK_VIEW);
1204
1205                         SItemInfo *itInfo = m_FindItemInfoFromItem(m->elInfo, item);
1206                         if (itInfo->select_status)
1207                                 elm_object_item_signal_emit(item,
1208                                         MUSIC_SIGNAL_SELECT_ITEM, MUSIC_PLAYBACK_VIEW);
1209                         else
1210                                 elm_object_item_signal_emit(item,
1211                                         MUSIC_SIGNAL_UNSELECT_ITEM, MUSIC_PLAYBACK_VIEW);
1212
1213                         if (itInfo->edit_mode) {
1214                                 elm_object_item_signal_emit(item,
1215                                         MUSIC_SIGNAL_EDITMODE_ON, MUSIC_PLAYBACK_VIEW);
1216                                 if (itInfo->check_status) {
1217                                         elm_object_item_signal_emit(item,
1218                                                 MUSIC_SIGNAL_CHECK_ON, MUSIC_PLAYBACK_VIEW);
1219                                 }
1220                                 else
1221                                         elm_object_item_signal_emit(item,
1222                                                 MUSIC_SIGNAL_CHECK_OFF, MUSIC_PLAYBACK_VIEW);
1223                         }
1224                         else
1225                                 elm_object_item_signal_emit(item,
1226                                         MUSIC_SIGNAL_EDITMODE_OFF, MUSIC_PLAYBACK_VIEW);
1227                 }
1228                 break;
1229
1230         default:
1231                 break;
1232         }
1233 }
1234
1235
1236 void CPlaybackView::OnActivated(int id, Evas_Object *obj, Elm_Object_Item *item)
1237 {
1238         switch (id) {
1239         case EO_PLAYLIST:
1240                 m_HandleGenlistItemActivated(obj, item);
1241                 break;
1242
1243         default:
1244                 break;
1245         }
1246 }
1247
1248
1249 void CPlaybackView::OnComplete(void)
1250 {
1251         m_UpdateCurrentSongInfo();
1252 }
1253
1254
1255 void CPlaybackView::OnError(void)
1256 {
1257 }
1258
1259
1260 void CPlaybackView::OnUsbStatusChanged(SUsbStorageStatus status)
1261 {
1262 }
1263
1264
1265 void CPlaybackView::OnUpdateContent(void)
1266 {
1267 }
1268
1269
1270 void CPlaybackView::OnStartPlayback(void)
1271 {
1272         m_UpdateCurrentSongInfo();
1273 }
1274
1275
1276 void CPlaybackView::OnStopPlayback(void)
1277 {
1278 }
1279
1280
1281 void CPlaybackView::OnEmptyPlaylist(void)
1282 {
1283         eina_list_free(m->elInfo);
1284         m->elInfo = NULL;
1285         elm_genlist_clear(m->eoPlaylist);
1286         m_UpdateEmptySongInfo();
1287 }
1288
1289
1290 void CPlaybackView::OnPlayerModeChanged(EPlayerMode mode)
1291 {
1292         switch (mode) {
1293         case MODE_PLAYLIST_EDIT:
1294                 m_FromPlaybackToEditMode();
1295                 break;
1296
1297         case MODE_PLAYBACK:
1298                 m_FromEditToPlaybackMode();
1299                 break;
1300
1301         default:
1302                 ASSERT(!"Invalid Player Mode");
1303                 break;
1304         }
1305 }
1306
1307
1308 void CPlaybackView::OnEditButtonsPressed(EPlayerEditBtns editBtns)
1309 {
1310         switch (editBtns) {
1311         case EDIT_BTN_CANCEL:
1312                 m_DisableCheckAll(m->elInfo);
1313                 m_DisableEditButtons(true);
1314                 break;
1315
1316         case EDIT_BTN_DESELECT:
1317                 m_DisableCheckAll(m->elInfo);
1318                 m_DisableEditButtons(true);
1319                 elm_genlist_realized_items_update(m->eoPlaylist);
1320                 break;
1321
1322         case EDIT_BTN_DELETE:
1323                 m_DeleteSelectedItems();
1324                 break;
1325
1326         default:
1327                 ASSERT(!"Invalid Edit Button");
1328                 break;
1329         }
1330 }