c7bb8b5c152ab64d18b5e4a3acbdf4c106bb8dc3
[profile/tv/apps/native/musicplayer.git] / src / views / category-layout.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 <Elementary.h>
18 #include <Eina.h>
19
20 #include "AppCommon.h"
21 #include <InputHandler.h>
22 #include <SortMgr.h>
23 #include "dbg.h"
24 #include "i18n.h"
25 #include "define.h"
26
27 #include "common.h"
28 #include "category_info.h"
29 #include "album_info.h"
30 #include "song_info.h"
31 #include "music-controller.h"
32 #include "LayoutMgr.h"
33 #include "entry-popup.h"
34 #include "common-ui.h"
35 #include "BaseView.h"
36 #include "ExtBaseLayout.h"
37 #include "ViewMgr.h"
38 #include "category-layout.h"
39 #include "base-view.h"
40 #include "Info.h"
41 #include "category-songs-layout.h"
42
43 #define TOTAL_ADD_BTNS 3
44 #define TOTAL_SELECT_BTNS 3
45 #define GENGRID_ITEM_SIZE_W (263+20)
46 #define GENGRID_ITEM_SIZE_H (359+20)
47
48
49 enum EObjectType {
50         CATEGORY_LAYOUT,
51         CATEGORY_LAYOUT_GENGRID,
52         CATEGORY_LAYOUT_PLAY_BUTTON,
53         CATEGORY_LAYOUT_NEXT_BUTTON,
54         CATEGORY_LAYOUT_LAST_BUTTON,
55 };
56
57 enum EAddBtns {
58         ABTN_PLAY,
59         ABTN_NEXT,
60         ABTN_LAST
61 };
62
63 enum EIdType {
64         ID_TYPE_MEDIA,
65         ID_TYPE_MEMBER
66 };
67
68 enum EFocusIderType {
69         IDLER_TYPE_LAYOUT_UPDATE,
70         IDLER_TYPE_FOCUS_MOVE_BY_USER_INPUT
71 };
72
73 struct SBtnInfo {
74         const char *name;
75         const char *part;
76         const char *style;
77         const char *icon;
78         EObjectType type;
79 };
80
81 struct SCallback {
82         void(*cbHandleEmptyStatus)(void *cookie, bool emptyStatus);
83         void *cookie;
84 };
85
86 struct SCategoryLayout {
87         Evas_Object *win;
88         Evas_Object *layout;
89         Evas_Object *addBtns[TOTAL_ADD_BTNS];
90         Evas_Object *def_foc_btn;
91         Eina_List *catlist;
92         Eina_List *alblist;
93         Eina_List *songlist;
94         Eina_List *it_infolist;
95         Ecore_Idler *focusIdler;
96         CMusicController *pMusicController;
97         CLayoutMgr *lmgr;
98         CViewMgr *vmgr;
99         CSongInfo *c_sinfo;
100         CCategorySongsLayout *layoutCatSongs;
101         SCallback callback;
102         int total_duration;
103         int count;
104
105         const char *focusBtnStr;
106         EFocusIderType idlerType;
107
108         const char *catSongLayoutId;
109
110         SCategoryLayout() {
111                 memset(this, 0, sizeof(SCategoryLayout));
112         }
113
114         ~SCategoryLayout() {
115         }
116 };
117
118
119 Eina_Bool CCategoryLayout::sm_CbFocusIdler(void *dt)
120 {
121         CCategoryLayout *root = (CCategoryLayout *)dt;
122
123         if (root)
124                 root->m_OnFocusIdler();
125
126         return ECORE_CALLBACK_CANCEL;
127 }
128
129
130 void CCategoryLayout::m_OnFocusIdler(void)
131 {
132         m->focusIdler = NULL;
133
134         if (m->idlerType == IDLER_TYPE_LAYOUT_UPDATE) {
135                 Elm_Object_Item *it = NULL;
136                 SCatItemInfo *itinfo = NULL;
137
138                 elm_object_tree_focus_allow_set(t.base, EINA_TRUE);
139
140                 if (t.depth == E_DEPTH_CATEGORY) {
141                         it = m_FindItemByInfo(m->it_infolist, t.c_catinfo);
142                         if (!it) {
143                                 itinfo = (SCatItemInfo *)eina_list_nth(m->it_infolist, 0);
144                                 it = itinfo->item;
145                         }
146                         elm_gengrid_item_show(it, ELM_GENGRID_ITEM_SCROLLTO_IN);
147                         elm_object_item_focus_set(it, EINA_TRUE);
148                 }
149                 else if (t.depth == E_DEPTH_ALBUM)
150                         elm_object_focus_set(m->def_foc_btn, EINA_TRUE);
151         }
152         else {
153                 Evas_Object *focus = NULL;
154
155                 if (t.depth == E_DEPTH_CATEGORY) {
156                         elm_gengrid_item_show(t.focused_item, ELM_GENGRID_ITEM_SCROLLTO_IN);
157                         elm_object_item_focus_set(t.focused_item, EINA_TRUE);
158                 }
159                 else if (t.depth == E_DEPTH_ALBUM) {
160                         if (!strcmp(m->focusBtnStr, MUSIC_FIRST_BTN))
161                                 focus = m->addBtns[ABTN_PLAY];
162                         else if (!strcmp(m->focusBtnStr, MUSIC_SECOND_BTN))
163                                 focus = m->addBtns[ABTN_NEXT];
164                         else // MUSIC_THIRD_BTN
165                                 focus = m->addBtns[ABTN_LAST];
166
167                         elm_object_focus_set(focus, EINA_TRUE);
168                 }
169         }
170 }
171
172
173 void CCategoryLayout::sm_CbEntrynameSet(void *dt, const char *name)
174 {
175         CCategoryLayout *root = (CCategoryLayout *)dt;
176         if (root)
177                 root->m_OnEntrynameSet(name);
178 }
179
180
181 void CCategoryLayout::m_OnEntrynameSet(const char *name)
182 {
183         Eina_List *idlist = NULL;
184         char *str = NULL;
185
186         if (!name)
187                 return;
188
189         idlist = m_GetSelectedList(m->layoutCatSongs->CategorySongItemInfoList(), (int)ID_TYPE_MEDIA);
190         str = strdup(name);
191         t.epopup->Destroy();
192
193         if (!strcmp(str, MUSIC_STR_EMPTY)) {
194                 CCommonUI::CreateMsgBox(Layout(), MUSIC_TEXT_EMPTY_NAME);
195                 free(str);
196                 return;
197         }
198
199         if (m->pMusicController->MediaExistPlaylist(str)) {
200                 CCommonUI::CreateMsgBox(Layout(), MUSIC_TEXT_INUSE_MSG);
201                 free(str);
202                 return;
203         }
204
205         if (!m->pMusicController->MediaInsertPlaylist(str, idlist)) {
206                 _ERR("Playlist creation failed ");
207                 free(str);
208                 return;
209         }
210
211         free(str);
212         t.depth = E_DEPTH_CATEGORY;
213         t_UpdateLayoutWithFocus();
214
215         SParcel parcel;
216         memset(&parcel, 0, sizeof(SParcel));
217         parcel.updateType = E_DEPTH_UPDATE;
218         parcel.layoutId = MUSIC_CATEGORY_PLAYLISTS_SONGS_LAYOUT;
219         m->vmgr->UpdateView((const char *)MUSIC_BASE_VIEW, &parcel);
220 }
221
222
223 void CCategoryLayout::sm_CbCtxtUpdate(void *dt, enum EActionType type, int lid)
224 {
225         CCategoryLayout *root = (CCategoryLayout *)dt;
226
227         if (root)
228                 root->t_OnCtxtUpdate(type, lid);
229 }
230
231
232 void CCategoryLayout::t_OnCtxtUpdate(enum EActionType type, int lid)
233 {
234         Eina_List *list = NULL;
235         Eina_List *alist = NULL, *slist = NULL, *l = NULL, *sl = NULL;
236         CSongInfo *sinfo = NULL;
237         CAlbumInfo *alinfo = NULL;
238         void *obj = NULL;
239         EAddType mode;
240
241         if (!t.ctxtinfo || !t.ctxtinfo->context)
242                 return;
243
244         if (type == ACTION_TYPE_ADDNEXT)
245                 mode = ADD_TYPE_NEXT;
246         else
247                 mode = ADD_TYPE_END;
248
249         if (t.depth == E_DEPTH_SONG) {
250                 sinfo = (CSongInfo *)t.ctxtinfo->context;
251                 list = eina_list_append(list, sinfo);
252         }
253         else if (t.depth == E_DEPTH_ALBUM) {
254                 m->pMusicController->MediaGetList(LIST_TYPE_ALBUM_SONG,
255                         t.ctxtinfo->context, &list);
256                 sinfo = (CSongInfo *)eina_list_data_get(list);
257         }
258         else {
259                 alist = ((CCategoryInfo *)t.ctxtinfo->context)->AlbumList();
260                 EINA_LIST_FOREACH(alist, l, obj) {
261                         alinfo = (CAlbumInfo *)obj;
262                         slist = NULL;
263                         if (!m->pMusicController->MediaGetList(LIST_TYPE_ALBUM_SONG, (void *)alinfo, &slist)) {
264                                 _ERR(" Failed to get album songlist ");
265                                 continue;
266                         }
267                         EINA_LIST_FOREACH(slist, sl, obj) {
268                                 sinfo = (CSongInfo *)obj;
269                                 CSongInfo *dupSongInfo = new CSongInfo;
270                                 dupSongInfo->Create();
271                                 dupSongInfo->Duplicate(sinfo);
272                                 list = eina_list_append(list, dupSongInfo);
273                         }
274                         eina_list_free(slist);
275                 }
276                 sinfo = (CSongInfo *)eina_list_data_get(list);
277         }
278
279         if (type ==  ACTION_TYPE_ADDTO) {
280                 if (!m->pMusicController->MediaAddsongsPlaylist(lid, list))
281                         _ERR(" Adding songs to playlist failed ");
282                 else
283                         CCommonUI::CreateMsgBox(t.base, MUSIC_TEXT_ADDTO_MSG);
284
285                 if (t.depth == E_DEPTH_CATEGORY) {
286                         EINA_LIST_FREE(list, obj) {
287                                 sinfo = (CSongInfo *)obj;
288                                 sinfo->Destroy();
289                                 delete sinfo;
290                         }
291                 }
292
293                 return;
294         }
295
296         m->pMusicController->UpdatePlaylist(list, mode);
297         if (type == ACTION_TYPE_PLAY) {
298                 m->pMusicController->Stop();
299                 m->pMusicController->SetCurrentSong(sinfo->Id());
300         }
301
302         if (t.depth == E_DEPTH_CATEGORY) {
303                 EINA_LIST_FREE(list, obj) {
304                         sinfo = (CSongInfo *)obj;
305                         sinfo->Destroy();
306                         delete sinfo;
307                 }
308         }
309         else {
310                 eina_list_free(list);
311         }
312
313         CCommonUI::UpdatePlaybackView((EAddType)type, Layout(), t.focused_item);
314 }
315
316
317 void CCategoryLayout::sm_CbCtxtClose(void *dt)
318 {
319         CCategoryLayout *root = (CCategoryLayout *)dt;
320         if (root)
321                 root->m_OnCtxtClose();
322 }
323
324
325 void CCategoryLayout::m_OnCtxtClose(void)
326 {
327         m->vmgr->PopView();
328         m->vmgr->PushView(MUSIC_BASE_VIEW, NULL);
329         elm_object_item_focus_set(t.focused_item, EINA_TRUE);
330 }
331
332
333 char *CCategoryLayout::sm_CbGetGridItemText(void *data, Evas_Object *obj, const char *part)
334 {
335         SCatItemInfo *itinfo = (SCatItemInfo *)data;
336         int scount, acount;
337         const char *txt = NULL;
338         char buf[MAX_LENGTH];
339
340         if (!itinfo || !obj || !part)
341                 return NULL;
342
343         if (!strcmp(part, "elm.text")) {
344                 if (itinfo->type == CAT_TYPE_PLAYLIST_NEW)
345                         return strdup(_(MUSIC_TEXT_CREATE_PLAYLIST));
346
347                 txt = itinfo->catinfo->Name();
348                 if (txt)
349                         return strdup(txt);
350         }
351         else if (!strcmp(part, "elm.text1")) {
352                 if (itinfo->type == CAT_TYPE_PLAYLIST_NEW) {
353                         return NULL;
354                 }
355                 else if (itinfo->type == CAT_TYPE_PLAYLISTS) {
356                         scount = itinfo->catinfo->SongCount();
357                         snprintf(buf, sizeof(buf), "%d %s", scount, _("Songs"));
358                 }
359                 else {
360                         acount = itinfo->catinfo->AlbumCount();
361                         scount = itinfo->catinfo->SongCount();
362                         snprintf(buf, sizeof(buf), "%d %s, %d %s", acount,
363                                 _("Albums"), scount, _("Songs"));
364                 }
365                 return strdup(buf);
366         }
367
368         return NULL;
369 }
370
371
372 char *CCategoryLayout::sm_CbGetGridAlbumItemText(void *data, Evas_Object *obj, const char *part)
373 {
374         SCatItemInfo *itinfo = (SCatItemInfo *)data;
375         CAlbumInfo *alinfo = NULL;
376         char *txt = NULL;
377
378         if (!itinfo || !obj || !part)
379                 return NULL;
380
381         alinfo = itinfo->alinfo;
382
383         if (!strcmp(part, "elm.text")) {
384                 txt = alinfo->Name();
385                 if (txt)
386                         return strdup(txt);
387         }
388         else if (!strcmp(part, "elm.text1")) {
389                 if (itinfo->type == CAT_TYPE_ARTIST)
390                         txt = alinfo->Artist();
391                 else
392                         txt = alinfo->Genre();
393                 if (txt)
394                         return strdup(txt);
395         }
396
397         return NULL;
398 }
399
400
401 Evas_Object *CCategoryLayout::sm_CbGetGridItemContent(void *data, Evas_Object *obj, const char *part)
402 {
403         SCatItemInfo *itinfo = (SCatItemInfo *)data;
404         CAlbumInfo *alinfo = NULL;
405         void *list_obj = NULL;
406         Eina_List *l = NULL, *alist = NULL;
407         Evas_Object *img = NULL;
408         char *path = NULL;
409         char buf[MAX_LENGTH];
410
411         if (!itinfo || !obj || !part)
412                 return NULL;
413
414         if (!itinfo->catinfo && itinfo->type != CAT_TYPE_PLAYLIST_NEW)
415                 return NULL;
416
417         if (strcmp(part, "elm.swallow.icon"))
418                 return NULL;
419
420         img = elm_image_add(obj);
421         if (!img)
422                 return NULL;
423
424         path = NULL;
425
426         if (itinfo->type == CAT_TYPE_ARTIST || itinfo->type == CAT_TYPE_GENRE) {
427                 alist = itinfo->catinfo->AlbumList();
428                 if (alist) {
429                         EINA_LIST_FOREACH(alist, l, list_obj) {
430                                 alinfo = (CAlbumInfo *)list_obj;
431                                 path = alinfo->ThumbnailPath();
432                                 if (path)
433                                         break;
434                         }
435                 }
436         }
437         else if (itinfo->type == CAT_TYPE_PLAYLISTS) {
438                 path = itinfo->catinfo->ThumbnailPath();
439         }
440
441         if (!path) {
442                 if (itinfo->type == CAT_TYPE_PLAYLIST_NEW)
443                         snprintf(buf, sizeof(buf), "%s/%s", IMAGEDIR,
444                         MUSIC_IMAGE_CREATE_PLAYLIST);
445                 else
446                         snprintf(buf, sizeof(buf), "%s/%s", IMAGEDIR,
447                         MUSIC_IMAGE_DEFAULT_THUMB_126);
448                 elm_image_file_set(img, buf, NULL);
449                 elm_image_no_scale_set(img, EINA_TRUE);
450         }
451         else {
452                 elm_image_file_set(img, path, NULL);
453                 elm_image_aspect_fixed_set(img, EINA_FALSE);
454         }
455
456         return img;
457 }
458
459
460 Evas_Object *CCategoryLayout::sm_CbGetGridAlbumitemContent(void *data, Evas_Object *obj, const char *part)
461 {
462         SCatItemInfo *itinfo = (SCatItemInfo *)data;
463         CAlbumInfo *alinfo = NULL;
464         char *path = NULL;
465         Evas_Object *img = NULL;
466         char buf[MAX_LENGTH];
467
468         if (!itinfo || !obj || !part)
469                 return NULL;
470
471         alinfo = itinfo->alinfo;
472
473         if (strcmp(part, "elm.swallow.icon"))
474                 return NULL;
475
476         img = elm_image_add(obj);
477         if (!img)
478                 return NULL;
479
480         path = alinfo->ThumbnailPath();
481         if (!path) {
482                 snprintf(buf, sizeof(buf), "%s/%s", IMAGEDIR,
483                         MUSIC_IMAGE_DEFAULT_THUMB_126);
484                 elm_image_file_set(img, buf, NULL);
485                 elm_image_no_scale_set(img, EINA_TRUE);
486         }
487         else {
488                 elm_image_file_set(img, path, NULL);
489                 elm_image_aspect_fixed_set(img, EINA_FALSE);
490         }
491
492         return img;
493 }
494
495
496 void CCategoryLayout::sm_CbRemoveGridItem(void *data, Evas_Object *obj)
497 {
498         free(data);
499 }
500
501
502 void CCategoryLayout::sm_CbItemSelect(void *data, Elm_Object_Item *it, const char *emission, const char *source)
503 {
504         CCategoryLayout *root = (CCategoryLayout *)data;
505         if (root)
506                 root->m_OnItemSelect(it, emission, source);
507 }
508
509
510 void CCategoryLayout::m_OnItemSelect(Elm_Object_Item *it, const char *emission, const char *source)
511 {
512         SCatItemInfo *itinfo = NULL;
513
514         itinfo = m_FindItemInfo(m->it_infolist, it);
515         if (!itinfo) {
516                 _ERR(" no item info found ");
517                 return;
518         }
519
520         if (t.depth == E_DEPTH_ALBUM) {
521                 if (!t.c_alinfo) {
522                         t.c_alinfo = new CAlbumInfo;
523                 }
524
525                 if (!t.c_alinfo->FlagCreate()) {
526                         t.c_alinfo->Create();
527                 }
528                 t.c_alinfo->Duplicate(itinfo->alinfo);
529                 t.depth = E_DEPTH_SONG;
530         }
531         else {
532                 if (t.c_catinfo && t.c_catinfo->FlagCreate())
533                         t.c_catinfo->Destroy();
534
535                 delete t.c_catinfo;
536                 t.c_catinfo = NULL;
537
538                 t_HandleItemSelect(itinfo);
539         }
540
541         t_UpdateLayoutWithFocus();
542 }
543
544
545 int CCategoryLayout::m_ConvertToMin(int milsec)
546 {
547         int min;
548
549         min = milsec / 60000;  /*milli seconds per minute*/
550
551         return min;
552 }
553
554
555 void CCategoryLayout::m_RemoveFocusIdler(void)
556 {
557         if (!m->focusIdler)
558                 return;
559
560         ecore_idler_del(m->focusIdler);
561         m->focusIdler = NULL;
562 }
563
564
565 Elm_Object_Item *CCategoryLayout::m_FindItemByInfo(Eina_List *list, void *info)
566 {
567         Eina_List *l = NULL;
568         SCatItemInfo *itinfo = NULL;
569         void *obj = NULL;
570         int id;
571
572         if (!list || !info)
573                 return NULL;
574
575         EINA_LIST_FOREACH(list, l, obj) {
576                 itinfo = (SCatItemInfo *)obj;
577                 if (!itinfo->catinfo)
578                         continue;
579
580                 id = itinfo->catinfo->CategoryId();
581                 if (id == ((CCategoryInfo *)info)->CategoryId())
582                         return itinfo->item;
583         }
584
585         return NULL;
586 }
587
588
589 CCategoryLayout::SCatItemInfo *CCategoryLayout::m_FindItemInfo(Eina_List *list, Elm_Object_Item *item)
590 {
591         Eina_List *l = NULL;
592         SCatItemInfo *itinfo = NULL;
593         void *obj = NULL;
594
595         if (!list || !item)
596                 return NULL;
597
598         EINA_LIST_FOREACH(list, l, obj) {
599                 itinfo = (SCatItemInfo *)obj;
600                 if (itinfo->item == item)
601                         return itinfo;
602         }
603
604         return NULL;
605 }
606
607
608 void CCategoryLayout::m_GotoPlayback(int mode, char *id)
609 {
610         if (!m->it_infolist || eina_list_count(m->it_infolist) == 0) {
611                 CCommonUI::CreateMsgBox(Layout(), MUSIC_TEXT_NO_SONGS);
612                 _ERR(" No songs for playback ");
613                 return;
614         }
615
616         if (t.depth == E_DEPTH_ALBUM)
617                 m_AddAlbumsToPlayback(mode);
618         else if (t.depth == E_DEPTH_SONG ||
619                 t.depth == E_DEPTH_SHOW_LIST)
620                 m_AddSongsToPlayback(mode);
621         else
622                 return;
623
624         if (mode == ADD_TYPE_FRESH) {
625                 m->pMusicController->Stop();
626                 if (id)   /* If want to play selected song */
627                         m->pMusicController->SetCurrentSong(id);
628         }
629
630         CCommonUI::UpdatePlaybackView((EAddType)mode, Layout(), NULL);
631 }
632
633
634 Eina_List *CCategoryLayout::m_GetSelectedList(Eina_List *infolist, int type)
635 {
636         Eina_List *idlist = NULL, *l = NULL;
637         CCategorySongsLayout::SCategorySongsItemsInfo *itinfo = NULL;
638         void *obj = NULL;
639         char *id = NULL;
640         EIdType eType = (EIdType)type;
641
642         if (!infolist)
643                 return NULL;
644
645         idlist = NULL;
646         EINA_LIST_FOREACH(infolist, l, obj) {
647                 itinfo = (CCategorySongsLayout::SCategorySongsItemsInfo *)obj;
648                 if (!itinfo->check_status)
649                         continue;
650
651                 if (eType == ID_TYPE_MEDIA) {
652                         id = itinfo->sinfo->Id();
653                         if (id)
654                                 idlist = eina_list_append(idlist, id);
655                 }
656                 else {
657                         idlist = eina_list_append(idlist,
658                                 itinfo->sinfo);
659                 }
660         }
661
662         return idlist;
663 }
664
665
666 void CCategoryLayout::m_AddAlbumsToPlayback(int mode)
667 {
668         Eina_List *l = NULL, *sl = NULL;
669         Eina_List *slist = NULL;
670         Eina_List *list = NULL;
671         CSongInfo *sinfo = NULL;
672         SCatItemInfo *itinfo = NULL;
673         void *obj = NULL;
674         Eina_List *infolist = m->it_infolist;
675         CMusicController *pMusicController = m->pMusicController;
676
677         list = NULL;
678         EINA_LIST_FOREACH(infolist, l, obj) {
679                 itinfo = (SCatItemInfo *)obj;
680                 slist = NULL;
681                 if (!pMusicController->MediaGetList(LIST_TYPE_ALBUM_SONG, itinfo->alinfo, &slist)) {
682                         _ERR(" Failed to get album songlist ");
683                         continue;
684                 }
685
686                 EINA_LIST_FOREACH(slist, sl, obj) {
687                         sinfo = (CSongInfo *)obj;
688                         CSongInfo *dupSongInfo = new CSongInfo;
689                         dupSongInfo->Create();
690                         dupSongInfo->Duplicate(sinfo);
691                         list = eina_list_append(list, dupSongInfo);
692                 }
693
694                 eina_list_free(slist);
695         }
696
697         pMusicController->UpdatePlaylist(list, mode);
698         EINA_LIST_FREE(list, obj) {
699                 sinfo = (CSongInfo *)obj;
700                 sinfo->Destroy();
701                 delete sinfo;
702         }
703 }
704
705
706 void CCategoryLayout::m_AddSongsToPlayback(int mode)
707 {
708         Eina_List *l = NULL;
709         Eina_List *list = NULL;
710         struct SCatItemInfo *itinfo = NULL;
711         void *obj = NULL;
712         Eina_List *infolist = m->it_infolist;
713         CMusicController *pMusicController = m->pMusicController;
714
715         list = NULL;
716         EINA_LIST_FOREACH(infolist, l, obj) {
717                 itinfo = (SCatItemInfo *)obj;
718                 list = eina_list_append(list, itinfo->sinfo);
719         }
720
721         pMusicController->UpdatePlaylist(list, mode);
722         eina_list_free(list);
723 }
724
725
726 Evas_Object *CCategoryLayout::m_AddGrid(void)
727 {
728         Evas_Object *grid = NULL;
729
730         grid = elm_gengrid_add(Layout());
731         if (!grid)
732                 return NULL;
733
734         evas_object_size_hint_weight_set(grid,
735                 EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
736         elm_gengrid_align_set(grid, 0, 0);
737
738         Connect(grid, CATEGORY_LAYOUT_GENGRID, TYPE_MOUSE_MOVE | TYPE_KEY_DOWN | TYPE_REALIZED | TYPE_UNREALIZED | TYPE_ACTIVATED);
739
740         elm_gengrid_item_size_set(grid,
741                 elm_config_scale_get() * GENGRID_ITEM_SIZE_W,
742                 elm_config_scale_get() * GENGRID_ITEM_SIZE_H);
743
744         return grid;
745 }
746
747
748 void CCategoryLayout::m_AddCategoryItem(Elm_Gengrid_Item_Class *grid_item, ECategoryType type, void *info)
749 {
750         SCatItemInfo *itinfo = NULL;
751         Elm_Object_Item *item = NULL;
752
753         if (!grid_item)
754                 return;
755
756         itinfo = (SCatItemInfo *)calloc(1, sizeof(*itinfo));
757         if (!itinfo)
758                 return;
759
760         itinfo->catinfo = (CCategoryInfo *)info;
761         itinfo->type = type;
762         item = elm_gengrid_item_append(t.grid,
763                 grid_item, itinfo, NULL, m);
764         itinfo->item = item;
765         m->it_infolist = eina_list_append(m->it_infolist,
766                 itinfo);
767 }
768
769
770 void CCategoryLayout::m_AddButtons(void)
771 {
772         int i;
773         Evas_Object *img = NULL;
774         char buf[MAX_LENGTH];
775         SBtnInfo btninfo[TOTAL_ADD_BTNS];
776
777         btninfo[ABTN_PLAY].name = MUSIC_STR_PLAY;
778         btninfo[ABTN_PLAY].part = MUSIC_PART_CATEGORY_PLAYBTN;
779         btninfo[ABTN_PLAY].style = MUSIC_STYLE_ADD_PLAY_BTN;
780         btninfo[ABTN_PLAY].icon = MUSIC_IMAGE_ADD_PLAY;
781         btninfo[ABTN_PLAY].type = CATEGORY_LAYOUT_PLAY_BUTTON;
782
783         btninfo[ABTN_NEXT].name = MUSIC_STR_ADDNEXT;
784         btninfo[ABTN_NEXT].part = MUSIC_PART_CATEGORY_NEXTBTN;
785         btninfo[ABTN_NEXT].style = MUSIC_STYLE_ADD_NEXT_BTN;
786         btninfo[ABTN_NEXT].icon = MUSIC_IMAGE_ADD_NEXT;
787         btninfo[ABTN_NEXT].type = CATEGORY_LAYOUT_NEXT_BUTTON;
788
789         btninfo[ABTN_LAST].name = MUSIC_STR_ADDLAST;
790         btninfo[ABTN_LAST].part = MUSIC_PART_CATEGORY_LASTBTN;
791         btninfo[ABTN_LAST].style = MUSIC_STYLE_ADD_LAST_BTN;
792         btninfo[ABTN_LAST].icon = MUSIC_IMAGE_ADD_LAST;
793         btninfo[ABTN_LAST].type = CATEGORY_LAYOUT_LAST_BUTTON;
794
795         if (t.depth == E_DEPTH_SHOW_LIST) {
796                 btninfo[ABTN_PLAY].part = MUSIC_PART_ALBUM_PLAYBTN;
797                 btninfo[ABTN_NEXT].part = MUSIC_PART_ALBUM_NEXTBTN;
798                 btninfo[ABTN_LAST].part = MUSIC_PART_ALBUM_LASTBTN;
799         }
800
801         for (i = 0; i < TOTAL_ADD_BTNS; i++) {
802                 m->addBtns[i] = elm_button_add(Layout());
803                 if (!m->addBtns[i])
804                         continue;
805
806                 evas_object_size_hint_weight_set(m->addBtns[i],
807                         EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
808                 elm_object_text_set(m->addBtns[i], _(btninfo[i].name));
809                 elm_object_style_set(m->addBtns[i], btninfo[i].style);
810
811                 Connect(m->addBtns[i], btninfo[i].type, TYPE_CLICKED | TYPE_MOUSE_MOVE | TYPE_KEY_DOWN);
812
813                 img = elm_image_add(m->addBtns[i]);
814                 if (img) {
815                         snprintf(buf, sizeof(buf), "%s/%s", IMAGEDIR,
816                                 btninfo[i].icon);
817                         elm_image_file_set(img, buf, NULL);
818                         elm_object_part_content_set(m->addBtns[i],
819                                 MUSIC_PART_ELM_SWALLOWICON, img);
820                 }
821
822                 elm_object_part_content_set(Layout(), btninfo[i].part, m->addBtns[i]);
823         }
824
825         elm_object_focus_set(m->addBtns[ABTN_PLAY], EINA_TRUE);
826         m->def_foc_btn = m->addBtns[ABTN_PLAY];
827 }
828
829
830 void CCategoryLayout::m_CreateAlbumgrid(void)
831 {
832         CAlbumInfo *alinfo = NULL;
833         void *obj = NULL;
834         Eina_List *l = NULL;
835         SCatItemInfo *itinfo = NULL;
836         Elm_Object_Item *item = NULL;
837         char buf[MAX_LENGTH];
838         Elm_Gengrid_Item_Class *grid_item = NULL;
839
840         if (!t.grid) {
841                 t.grid = m_AddGrid();
842                 if (!t.grid)
843                         return;
844         }
845
846         grid_item = elm_gengrid_item_class_new();
847         if (!grid_item) {
848                 evas_object_del(t.grid);
849                 _ERR(" elm_genlist_item_class_new failed ");
850                 return;
851         }
852         grid_item->item_style = MUSIC_STYLE_CATEGORY_GRID;
853         grid_item->func.text_get = sm_CbGetGridAlbumItemText;
854         grid_item->func.content_get = sm_CbGetGridAlbumitemContent;
855         grid_item->func.state_get = NULL;
856         grid_item->func.del = sm_CbRemoveGridItem;
857
858         m->alblist = t.c_catinfo->AlbumList();
859         if (!m->alblist || eina_list_count(m->alblist) == 0) {
860                 _ERR(" Fetching album list failed ");
861                 evas_object_del(t.grid);
862                 elm_gengrid_item_class_free(grid_item);
863                 return;
864         }
865
866         int i = 0;
867         EINA_LIST_FOREACH(m->alblist, l, obj) {
868                 alinfo = (CAlbumInfo *)obj;
869                 itinfo = (SCatItemInfo *)calloc(1, sizeof(*itinfo));
870                 if (!itinfo)
871                         return;
872                 itinfo->alinfo = alinfo;
873                 item = elm_gengrid_item_append(t.grid,
874                         grid_item, itinfo, NULL, m);
875                 itinfo->item = item;
876                 m->it_infolist = eina_list_append(m->it_infolist,
877                         itinfo);
878                 if (i == 0)
879                         t.focused_item = item;
880                 i++;
881         }
882         elm_gengrid_item_class_free(grid_item);
883
884         elm_object_part_text_set(Layout(),
885                 MUSIC_PART_CATEGORY_NAME,
886                 t.c_catinfo->Name());
887         snprintf(buf, sizeof(buf), "%d",
888                 t.c_catinfo->AlbumCount());
889         elm_object_part_text_set(Layout(),
890                 MUSIC_PART_CATEGORY_ALBUMCOUNT, buf);
891         snprintf(buf, sizeof(buf), "%d",
892                 t.c_catinfo->SongCount());
893         elm_object_part_text_set(Layout(),
894                 MUSIC_PART_CATEGORY_SONGCOUNT, buf);
895         elm_object_part_content_set(Layout(),
896                 MUSIC_PART_CATEGORY_ALBUM_GRID, t.grid);
897 }
898
899
900 void CCategoryLayout::m_CreateCatgrid(bool sort_flag)
901 {
902         void *info = NULL;
903         Eina_List *l = NULL;
904         Elm_Gengrid_Item_Class *grid_item = NULL;
905
906         if (!t.grid) {
907                 t.grid = m_AddGrid();
908                 if (!t.grid)
909                         return;
910         }
911
912         grid_item = elm_gengrid_item_class_new();
913         if (!grid_item) {
914                 evas_object_del(t.grid);
915                 _ERR(" elm_genlist_item_class_new failed ");
916                 return;
917         }
918         grid_item->item_style = MUSIC_STYLE_CATEGORY_GRID;
919         grid_item->func.text_get = sm_CbGetGridItemText;
920         grid_item->func.content_get = sm_CbGetGridItemContent;
921         grid_item->func.state_get = NULL;
922         grid_item->func.del = sm_CbRemoveGridItem;
923
924         if (!sort_flag) {
925                 if (!t_GetMediaList(&m->catlist)) {
926                         if (t_CategoryType() != CAT_TYPE_PLAYLISTS)  {
927                                 _ERR(" Fetching list  failed ");
928                                 SetEmptyStatus(true);
929                                 elm_gengrid_item_class_free(grid_item);
930                                 return;
931                         }
932                 }
933         }
934         m_SortCatgrid();
935
936         if (t_CategoryType() == CAT_TYPE_PLAYLISTS)
937                 m_AddCategoryItem(grid_item, CAT_TYPE_PLAYLIST_NEW, NULL);
938
939         EINA_LIST_FOREACH(m->catlist, l, info)
940                 m_AddCategoryItem(grid_item, t_CategoryType(), info);
941
942         elm_gengrid_item_class_free(grid_item);
943
944         elm_object_part_content_set(Layout(),
945                 MUSIC_PART_CATEGORY_GRID, t.grid);
946 }
947
948
949 void CCategoryLayout::m_SortCatgrid(void)
950 {
951         const char *sortFuncType[] = {
952                 SORT_BY_NAME_AZ,
953                 SORT_BY_NAME_ZA
954         };
955
956         if (!m->catlist)
957                 return;
958
959         int sortType;
960
961         sortType = CInfo::SortType();
962
963         m->catlist = CSortMgr::Sort(m->catlist, sortFuncType[sortType]);
964 }
965
966
967 void CCategoryLayout::m_EmptyLayout(bool sort_flag)
968 {
969         if (t.grid) {
970                 elm_gengrid_clear(t.grid);
971         }
972
973         if (!sort_flag) {
974                 if (m->catlist)
975                         eina_list_free(m->catlist);
976                 m->catlist = NULL;
977         }
978
979         // This value is just referenced from CCategoryInfo.
980         // So should not freed here.
981         m->alblist = NULL;
982
983         if (m->songlist)
984                 eina_list_free(m->songlist);
985         m->songlist = NULL;
986
987         if (m->it_infolist)
988                 eina_list_free(m->it_infolist);
989         m->it_infolist = NULL;
990
991         m->total_duration = 0;
992
993         int i;
994
995         for (i = 0; i < TOTAL_ADD_BTNS; i++) {
996                 if (m->addBtns[i])
997                         evas_object_del(m->addBtns[i]);
998                 m->addBtns[i] = NULL;
999         }
1000 }
1001
1002
1003 void CCategoryLayout::m_ShowCategorySongs(void)
1004 {
1005         elm_object_part_content_unset(t.base, MUSIC_PART_CONTENT);
1006
1007         bool emptyStatus = m->layoutCatSongs->EmptyStatus();
1008
1009         if (emptyStatus == false) {
1010                 elm_object_part_content_set(t.base, MUSIC_PART_CONTENT, m->layoutCatSongs->Layout());
1011                 m->lmgr->Show(m->catSongLayoutId);
1012         }
1013
1014         if (m->callback.cbHandleEmptyStatus != NULL) {
1015                 m->callback.cbHandleEmptyStatus(m->callback.cookie, emptyStatus);
1016         }
1017 }
1018
1019
1020 const char *CCategoryLayout::m_CategorySongLayoutId(void)
1021 {
1022         const char *layoutId = NULL;
1023
1024         if (!strcmp(LayoutId(), MUSIC_CATEGORY_ARTIST_LAYOUT))
1025                 layoutId = MUSIC_CATEGORY_ARTIST_SONGS_LAYOUT;
1026         else if (!strcmp(LayoutId(), MUSIC_CATEGORY_GENRE_LAYOUT))
1027                 layoutId = MUSIC_CATEGORY_GENRE_SONGS_LAYOUT;
1028         else if (!strcmp(LayoutId(), MUSIC_CATEGORY_PLAYLISTS_LAYOUT))
1029                 layoutId = MUSIC_CATEGORY_PLAYLISTS_SONGS_LAYOUT;
1030
1031         return layoutId;
1032 }
1033
1034
1035 bool CCategoryLayout::t_SetEdje(const char *szLayout)
1036 {
1037         ASSERT(szLayout);
1038         if (!elm_layout_file_set(Layout(), EDJEFILE, szLayout)) {
1039                 _ERR(" elm szLayout file set failed ");
1040                 return false;
1041         }
1042         return true;
1043 }
1044
1045
1046 void CCategoryLayout::t_UpdateLayout(bool sort_flag)
1047 {
1048         /* Remove existing grid and prepare afresh */
1049         m_EmptyLayout(sort_flag);
1050
1051         SParcel parcel;
1052         memset(&parcel, 0, sizeof(SParcel));
1053
1054         if (t.depth == E_DEPTH_SONG) {
1055                 m->layoutCatSongs->SetParameter(CCategorySongsLayout::DEPTH_SONG_LIST, (CCategorySongsLayout::ESelectType)t.sel_type, t.c_catinfo, t.c_alinfo);
1056                 m_ShowCategorySongs();
1057
1058                 parcel.updateType = E_LAYOUT_UPDATE;
1059                 parcel.layoutId = MUSIC_CATEGORY_SONGS_LAYOUT;
1060                 m->vmgr->UpdateView((const char *)MUSIC_BASE_VIEW, &parcel);
1061         }
1062         else if (t.depth == E_DEPTH_SHOW_LIST) {
1063                 m->layoutCatSongs->SetParameter(CCategorySongsLayout::DEPTH_SHOW_LIST, (CCategorySongsLayout::ESelectType)t.sel_type, t.c_catinfo, t.c_alinfo);
1064                 m_ShowCategorySongs();
1065
1066                 parcel.updateType = E_LAYOUT_UPDATE;
1067                 parcel.layoutId = MUSIC_CATEGORY_SONGS_LAYOUT;
1068                 m->vmgr->UpdateView((const char *)MUSIC_BASE_VIEW, &parcel);
1069         }
1070         else if (t.depth == E_DEPTH_ALBUM) {
1071                 if (!t_SetEdje(MUSIC_CATEGORY_ALBUM_LAYOUT)) {
1072                         _ERR(" get layout failed ");
1073                         return;
1074                 }
1075                 m_AddButtons();
1076                 m_CreateAlbumgrid();
1077
1078                 parcel.updateType = E_LAYOUT_UPDATE;
1079                 parcel.layoutId = MUSIC_CATEGORY_ALBUM_LAYOUT;
1080                 m->vmgr->UpdateView((const char *)MUSIC_BASE_VIEW, &parcel);
1081         }
1082         else if (t.depth == E_DEPTH_SELECT_LIST) {
1083                 m->layoutCatSongs->SetParameter(CCategorySongsLayout::DEPTH_SELECT_LIST, (CCategorySongsLayout::ESelectType)t.sel_type, t.c_catinfo, t.c_alinfo);
1084                 m_ShowCategorySongs();
1085
1086                 parcel.updateType = E_LAYOUT_UPDATE;
1087                 parcel.layoutId = MUSIC_CATEGORY_SELECTLIST_LAYOUT;
1088                 m->vmgr->UpdateView((const char *)MUSIC_BASE_VIEW, &parcel);
1089         }
1090         else { // E_DEPTH_CATEGORY
1091                 if (!t_SetEdje(MUSIC_CATEGORY_LAYOUT)) {
1092                         _ERR(" get layout failed ");
1093                         return;
1094                 }
1095                 m_CreateCatgrid(sort_flag);
1096
1097                 parcel.updateType = E_LAYOUT_UPDATE;
1098                 parcel.layoutId = MUSIC_CATEGORY_LAYOUT;
1099                 m->vmgr->UpdateView((const char *)MUSIC_BASE_VIEW, &parcel);
1100         }
1101 }
1102
1103
1104 void CCategoryLayout::t_UpdateLayoutWithFocus(void)
1105 {
1106         bool needFocusIdler = false;
1107
1108         if (t.depth == E_DEPTH_ALBUM || t.depth == E_DEPTH_CATEGORY)
1109                 needFocusIdler = true;
1110
1111         if (needFocusIdler)
1112                 elm_object_tree_focus_allow_set(t.base, EINA_FALSE);
1113
1114         t_UpdateLayout(false);
1115
1116         if (needFocusIdler) {
1117                 m_RemoveFocusIdler();
1118                 m->idlerType = IDLER_TYPE_LAYOUT_UPDATE;
1119                 m->focusIdler = ecore_idler_add(sm_CbFocusIdler, this);
1120         }
1121 }
1122
1123
1124 bool CCategoryLayout::Create(CLayoutMgr *mgr)
1125 {
1126         ASSERT(!m);
1127         ASSERT(mgr);
1128
1129         _CREATE_BEGIN{
1130                 Evas_Object *base = NULL;
1131                 Evas_Object *win = NULL;
1132                 Evas_Object *layout = NULL;
1133                 CMusicController *pMusicController = NULL;
1134                 CViewMgr *vmgr = NULL;
1135                 CEntryPopup *popup = NULL;
1136                 CCategorySongsLayout *layoutCatSongs = NULL;
1137                 const char *catSongLayoutId = NULL;
1138
1139                 _CHECK(m = new SCategoryLayout)
1140                 _CHECK(vmgr = CViewMgr::GetInstance())
1141                 _CHECK(base = mgr->Base())
1142                 _CHECK(win = vmgr->Window())
1143                 _CHECK(pMusicController = CMusicController::GetInstance())
1144                 _CHECK(layout = elm_layout_add(base))
1145                 _CHECK(CExtBaseLayout::Create(layout))
1146                 _CHECK(popup = new CEntryPopup)
1147                 _CHECK(catSongLayoutId = m_CategorySongLayoutId())
1148                 _CHECK(layoutCatSongs = new CCategorySongsLayout(catSongLayoutId))
1149                 _CHECK(layoutCatSongs->Create(mgr, this))
1150                 _CHECK(mgr->AddLayout(layoutCatSongs))
1151
1152                 _WHEN_SUCCESS{
1153                         memset(&t, 0, sizeof(SCategoryLayoutProtected));
1154
1155                         m->win = win;
1156                         t.base = base;
1157                         m->vmgr = vmgr;
1158                         m->pMusicController = pMusicController;
1159                         m->lmgr = mgr;
1160                         t.depth = E_DEPTH_CATEGORY;
1161                         m->callback.cbHandleEmptyStatus = NULL;
1162                         m->callback.cookie = NULL;
1163                         t.epopup = popup;
1164                         m->catSongLayoutId = catSongLayoutId;
1165                         m->layoutCatSongs = layoutCatSongs;
1166
1167                         t_UpdateLayout(false);
1168
1169                         Connect(Layout(), CATEGORY_LAYOUT, TYPE_KEY_DOWN);
1170                 }
1171
1172                 _CHECK_FAIL{ mgr->RemoveLayout(layoutCatSongs); }
1173                 _CHECK_FAIL{ m->layoutCatSongs->Destroy(); }
1174                 _CHECK_FAIL{ delete layoutCatSongs; }
1175                 _CHECK_FAIL{}
1176                 _CHECK_FAIL{ delete popup; }
1177                 _CHECK_FAIL{ CExtBaseLayout::Destroy(); }
1178                 _CHECK_FAIL{ evas_object_del(layout); }
1179                 _CHECK_FAIL{}
1180                 _CHECK_FAIL{}
1181                 _CHECK_FAIL{}
1182                 _CHECK_FAIL{}
1183                 _CHECK_FAIL{ delete m; m = NULL; }
1184         } _CREATE_END_AND_CATCH{ return false; }
1185
1186         return true;
1187 }
1188
1189
1190 void CCategoryLayout::Destroy(void)
1191 {
1192         ASSERT(m);
1193
1194         Disconnect(Layout());
1195
1196         m->lmgr->RemoveLayout(m->layoutCatSongs);
1197         m->layoutCatSongs->Destroy();
1198         delete m->layoutCatSongs;
1199
1200         if (t.epopup->FlagCreate())
1201                 t.epopup->Destroy();
1202         delete t.epopup;
1203
1204         m_RemoveFocusIdler();
1205         m_EmptyLayout(false);
1206
1207         if (t.c_catinfo && t.c_catinfo->FlagCreate())
1208                 t.c_catinfo->Destroy();
1209         delete t.c_catinfo;
1210
1211         if (t.c_alinfo && t.c_alinfo->FlagCreate())
1212                 t.c_alinfo->Destroy();
1213         delete t.c_alinfo;
1214
1215         CExtBaseLayout::Destroy();
1216         evas_object_del(Layout());
1217
1218         delete m;
1219         m = NULL;
1220 }
1221
1222
1223 void CCategoryLayout::t_OnShow(void)
1224 {;
1225         ASSERT(m);
1226
1227         t.depth = E_DEPTH_CATEGORY;
1228         t_UpdateLayout(false);
1229         evas_object_show(Layout());
1230 }
1231
1232
1233 void CCategoryLayout::Update(bool focusFlag)
1234 {
1235         ASSERT(m);
1236
1237         if (!focusFlag) {
1238                 if (t.depth != E_DEPTH_CATEGORY)
1239                         return;
1240                 t_UpdateLayout(true);
1241                 return;
1242         }
1243
1244         elm_object_focus_set(t.grid, EINA_TRUE);
1245 }
1246
1247
1248 void CCategoryLayout::CreateEntryPopup(void)
1249 {
1250         ASSERT(m);
1251
1252         if (t.epopup->FlagCreate())
1253                 t.epopup->Destroy();
1254
1255         t.epopup->Create(t.base, MUSIC_STR_EMPTY, sm_CbEntrynameSet, this);
1256 }
1257
1258
1259 void CCategoryLayout::SetEmptyStatusHandleCallback(void(*handleEmptyStatusCb)(void *cookie, bool emptyStatus), void *cookie)
1260 {
1261         ASSERT(m);
1262
1263         m->callback.cbHandleEmptyStatus = handleEmptyStatusCb;
1264         m->callback.cookie = cookie;
1265 }
1266
1267
1268 void CCategoryLayout::SetFocus(const char *btnStr)
1269 {
1270         ASSERT(m);
1271
1272         m->idlerType = IDLER_TYPE_FOCUS_MOVE_BY_USER_INPUT;
1273         m->focusBtnStr = btnStr;
1274         m->focusIdler = ecore_idler_add(sm_CbFocusIdler, this);
1275 }
1276
1277
1278 void CCategoryLayout::OnKeyDown(int id, Evas *e, Evas_Object *obj, Evas_Event_Key_Down *ev)
1279 {
1280         switch (id) {
1281         case CATEGORY_LAYOUT:
1282                 {
1283                         int count;
1284                         Eina_List *alist = NULL;
1285
1286                         if (!strcmp(ev->keyname, KEY_BACK) ||
1287                                 !strcmp(ev->keyname, KEY_BACK_REMOTE)) {
1288                                 if (t.depth == E_DEPTH_CATEGORY) {
1289                                         SParcel parcel;
1290                                         memset(&parcel, 0, sizeof(SParcel));
1291                                         parcel.updateType = E_FOCUS_UPDATE;
1292                                         m->vmgr->UpdateView((const char *)MUSIC_BASE_VIEW, &parcel);
1293                                         return;
1294                                 }
1295                                 else if (t.depth == E_DEPTH_ALBUM) {
1296                                         t.depth = E_DEPTH_CATEGORY;
1297                                 }
1298                                 else if (t.depth == E_DEPTH_SELECT_LIST) {
1299                                         t.depth = E_DEPTH_CATEGORY;
1300                                 }
1301                                 else if (t.depth == E_DEPTH_SHOW_LIST) {
1302                                         t.depth = E_DEPTH_CATEGORY;
1303                                 }
1304                                 else if (t.depth == E_DEPTH_SONG) {
1305                                         count = 0;
1306                                         alist = t.c_catinfo->AlbumList();
1307                                         if (alist)
1308                                                 count = eina_list_count(alist);
1309                                         if (count == 1)
1310                                                 t.depth = E_DEPTH_CATEGORY;
1311                                         else
1312                                                 t.depth = E_DEPTH_ALBUM;
1313                                 }
1314
1315                                 t_UpdateLayoutWithFocus();
1316                         }
1317                 }
1318                 break;
1319
1320         case CATEGORY_LAYOUT_GENGRID:
1321                 {
1322                         Elm_Object_Item *it = NULL;
1323                         SContentInfo *ctxtinfo = NULL;
1324                         SCatItemInfo *itinfo = NULL;
1325
1326                         if (!obj)
1327                                 return;
1328
1329                         it = elm_object_focused_item_get(obj);
1330                         if (!it) {
1331                                 _ERR(" unable to get focused item ");
1332                                 return;
1333                         }
1334
1335                         t.focused_item = it;
1336
1337                         if ((!strcmp(ev->keyname, KEY_MENU) ||
1338                                 !strcmp(ev->keyname, KEY_MENU_REMOTE)) &&
1339                                 t.depth != E_DEPTH_SELECT_LIST &&
1340                                 t.depth != E_DEPTH_SHOW_LIST) {
1341                                 if (t.ctxtinfo) {
1342                                         free(t.ctxtinfo);
1343                                         t.ctxtinfo = NULL;
1344                                 }
1345
1346                                 ctxtinfo = (SContentInfo *)calloc(1, sizeof(*ctxtinfo));
1347                                 if (!ctxtinfo)
1348                                         return;
1349
1350                                 itinfo = m_FindItemInfo(m->it_infolist, it);
1351                                 if (!itinfo || itinfo->type == CAT_TYPE_PLAYLIST_NEW) {
1352                                         free(ctxtinfo);
1353                                         return;
1354                                 }
1355
1356                                 ctxtinfo->cbdata = this;
1357                                 ctxtinfo->update = sm_CbCtxtUpdate;
1358                                 ctxtinfo->close = sm_CbCtxtClose;
1359                                 if (t.depth == E_DEPTH_SONG) {
1360                                         ctxtinfo->type = CONTEXT_TYPE_SONG;
1361                                         ctxtinfo->context = itinfo->sinfo;
1362                                 }
1363                                 else if (t.depth == E_DEPTH_ALBUM) {
1364                                         ctxtinfo->type = CONTEXT_TYPE_ALBUM;
1365                                         ctxtinfo->context = itinfo->alinfo;
1366                                 }
1367                                 else {
1368                                         ctxtinfo->type = t_ContextType();
1369                                         ctxtinfo->context = itinfo->catinfo;
1370                                 }
1371
1372                                 t.ctxtinfo = ctxtinfo;
1373
1374                                 SParcel parcel;
1375                                 memset(&parcel, 0, sizeof(SParcel));
1376                                 parcel.ctxtInfo = ctxtinfo;
1377                                 if (!m->vmgr->PushView(MUSIC_CONTEXT_VIEW, &parcel))
1378                                         _ERR("viewmgr push view MUSIC_CONTEXT_VIEW failed");
1379                         }
1380                 }
1381                 break;
1382
1383         case CATEGORY_LAYOUT_PLAY_BUTTON:
1384         case CATEGORY_LAYOUT_NEXT_BUTTON:
1385         case CATEGORY_LAYOUT_LAST_BUTTON:
1386                 if (!strcmp(ev->keyname, KEY_UP)) {
1387                         const char *btnText = NULL;
1388
1389                         if (id == CATEGORY_LAYOUT_PLAY_BUTTON)
1390                                 btnText = MUSIC_FIRST_BTN;
1391                         else if (id == CATEGORY_LAYOUT_NEXT_BUTTON)
1392                                 btnText = MUSIC_SECOND_BTN;
1393                         else //CATEGORY_LAYOUT_LAST_BUTTON
1394                                 btnText = MUSIC_THIRD_BTN;
1395
1396                         SParcel parcel;
1397                         memset(&parcel, 0, sizeof(SParcel));
1398                         parcel.updateType = E_FOCUS_UPDATE;
1399                         parcel.keyEvent = KEY_UP;
1400                         parcel.focusedBtn = btnText;
1401                         m->vmgr->UpdateView((const char *)MUSIC_BASE_VIEW, &parcel);
1402                 }
1403                 break;
1404
1405         default:
1406                 break;
1407         }
1408 }
1409
1410
1411 void CCategoryLayout::OnMouseClicked(int id, Evas_Object *obj)
1412 {
1413         switch (id)
1414         {
1415         case CATEGORY_LAYOUT_PLAY_BUTTON:
1416                 m_GotoPlayback(ADD_TYPE_FRESH, NULL);
1417                 break;
1418
1419         case CATEGORY_LAYOUT_NEXT_BUTTON:
1420                 m_GotoPlayback(ADD_TYPE_NEXT, NULL);
1421                 break;
1422
1423         case CATEGORY_LAYOUT_LAST_BUTTON:
1424                 m_GotoPlayback(ADD_TYPE_END, NULL);
1425                 break;
1426
1427         default:
1428                 break;
1429         }
1430 }
1431
1432
1433 void CCategoryLayout::OnMouseMove(int id, Evas *e, Evas_Object *obj, Evas_Event_Mouse_Move *ev)
1434 {
1435         switch (id) {
1436         case CATEGORY_LAYOUT_PLAY_BUTTON:
1437         case CATEGORY_LAYOUT_NEXT_BUTTON:
1438         case CATEGORY_LAYOUT_LAST_BUTTON:
1439                 {
1440                         if (!elm_object_focus_get(obj))
1441                                 elm_object_focus_set(obj, EINA_TRUE);
1442                 }
1443                 break;
1444
1445         case CATEGORY_LAYOUT_GENGRID:
1446                 {
1447                         Elm_Object_Item *item;
1448
1449                         if (!obj)
1450                                 return;
1451
1452                         item = elm_gengrid_at_xy_item_get(obj, ev->cur.canvas.x,
1453                                 ev->cur.canvas.y, NULL, NULL);
1454                         if (!item)
1455                                 return;
1456
1457                         if (!elm_object_item_focus_get(item))
1458                                 elm_object_item_focus_set(item, EINA_TRUE);
1459
1460                         t.focused_item = item;
1461                 }
1462                 break;
1463
1464         default:
1465                 break;
1466         }
1467 }
1468
1469
1470 void CCategoryLayout::OnRealized(int id, Evas_Object *obj, Elm_Object_Item *item)
1471 {
1472         switch (id) {
1473         case CATEGORY_LAYOUT_GENGRID:
1474                 elm_object_item_signal_callback_add(item,
1475                         MUSIC_SIGNAL_BTN_CLICKED, MUSIC_BASE_VIEW,
1476                         sm_CbItemSelect, this);
1477                 break;
1478
1479         default:
1480                 break;
1481         }
1482 }
1483
1484
1485 void CCategoryLayout::OnUnrealized(int id, Evas_Object *obj, Elm_Object_Item *item)
1486 {
1487         switch (id) {
1488         case CATEGORY_LAYOUT_GENGRID:
1489                 elm_object_item_signal_callback_del(item,
1490                         MUSIC_SIGNAL_BTN_CLICKED, MUSIC_BASE_VIEW,
1491                         sm_CbItemSelect);
1492                 break;
1493
1494         default:
1495                 break;
1496         }
1497 }
1498
1499
1500 void CCategoryLayout::OnActivated(int id, Evas_Object *obj, Elm_Object_Item *item)
1501 {
1502         switch (id) {
1503         case CATEGORY_LAYOUT_GENGRID:
1504                 m_OnItemSelect(item, NULL, NULL);
1505                 break;
1506
1507         default:
1508                 break;
1509         }
1510 }