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