Apply IActivatedListener for gengrid / genlist.
[profile/tv/apps/native/musicplayer.git] / src / views / folder-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 #include <utilX.h>
20 #include "AppCommon.h"
21 #include "dbg.h"
22 #include "i18n.h"
23 #include "define.h"
24 #include <SortMgr.h>
25 #include <Sort.h>
26 #include "folder_info.h"
27 #include "song_info.h"
28 #include "album_info.h"
29
30 #include <InputHandler.h>
31 #include "music-controller.h"
32 #include "LayoutMgr.h"
33 #include "common.h"
34 #include "common-ui.h"
35 #include "BaseView.h"
36 #include "ExtBaseLayout.h"
37 #include "ViewMgr.h"
38 #include "folder-layout.h"
39 #include "base-view.h"
40
41 #define TOTAL_ADD_BTNS  3
42 #define GENGRID_ITEM_SIZE_W (263+20)
43 #define GENGRID_ITEM_SIZE_H (359+20)
44
45
46 enum EObjectType {
47         FOLDER_LAYOUT,
48         FOLDER_LAYOUT_GENGRID,
49         FOLDER_LAYOUT_PLAY_BUTTON,
50         FOLDER_LAYOUT_NEXT_BUTTON,
51         FOLDER_LAYOUT_LAST_BUTTON,
52 };
53
54 enum EBtnType {
55         BTN_PLAY,
56         BTN_NEXT,
57         BTN_LAST
58 };
59
60 struct SFolderItemInfo {
61         CFolderInfo *finfo;
62         CSongInfo *sinfo;
63         Elm_Object_Item *item;
64         int depth;
65 };
66
67 const char *g_sourceTexts[] = {
68         N_("All Source"), // SOURCE_TYPE_ALL
69         N_("TV"),         // SOURCE_TYPE_TV
70         N_("USB")         // SOURCE_TYPE_USB
71 };
72
73 enum EDepthType {
74         E_DEPTH_NONE,
75         E_DEPTH_FOLDER,
76         E_DEPTH_SONG
77 };
78
79 struct SBtnInfo {
80         const char *name;
81         const char *part;
82         const char *style;
83         const char *icon;
84         EObjectType type;
85 };
86
87 struct SFolderLayout {
88         Evas_Object *win;
89         Evas_Object *base;
90         Evas_Object *grid;
91         Elm_Object_Item *focused_item;
92         Eina_List *flist;
93         Eina_List *slist;
94         Eina_List *it_infolist;
95         Elm_Gengrid_Item_Class *item_class;
96         Elm_Gengrid_Item_Class *songitem_class;
97         Ecore_Idler *focus_idler;
98         CMusicController *mhandle;
99         CLayoutMgr *lmgr;
100         CViewMgr *vmgr;
101         CFolderInfo *c_finfo;
102         CSongInfo *c_sinfo;
103         SContentInfo *ctxtinfo;
104         CFolderLayout *parent;
105         int depth;
106
107         SFolderLayout() {
108                 memset(this, 0, sizeof(SFolderLayout));
109         }
110
111         ~SFolderLayout() {
112         }
113 };
114
115
116 char *CFolderLayout::sm_CbGetGridItemText(void *data, Evas_Object *obj, const char *part)
117 {
118         SFolderItemInfo *itinfo = (SFolderItemInfo *)data;
119         CFolderInfo *finfo = NULL;
120         char *txt = NULL;
121         char buf[MAX_LENGTH];
122         int count;
123
124         if (!itinfo || !obj)
125                 return NULL;
126
127         finfo = itinfo->finfo;
128
129         if (!strcmp(part, "elm.text")) {
130                 txt = finfo->Name();
131                 if (txt)
132                         return strdup(txt);
133         }
134         else if (!strcmp(part, "elm.text1")) {
135                 count = finfo->Count();
136                 snprintf(buf, sizeof(buf), "%d Songs", count);
137                 return strdup(buf);
138         }
139
140         return NULL;
141 }
142
143
144 char *CFolderLayout::sm_CbGetGridSongItemText(void *data, Evas_Object *obj, const char *part)
145 {
146         SFolderItemInfo *itinfo = (SFolderItemInfo *)data;
147         CSongInfo *sinfo = NULL;
148         char *txt = NULL;
149
150         if (!itinfo || !obj)
151                 return NULL;
152
153         sinfo = itinfo->sinfo;
154
155         if (!strcmp(part, "elm.text"))
156                 txt = sinfo->Name();
157         else if (!strcmp(part, "elm.text1"))
158                 txt = sinfo->Artist();
159
160         if (txt)
161                 return strdup(txt);
162
163         return NULL;
164 }
165
166
167 Evas_Object *CFolderLayout::sm_CbGetGridItemContent(void *data, Evas_Object *obj, const char *part)
168 {
169         Evas_Object *img = NULL;
170         char buf[MAX_LENGTH];
171
172         if (!data || !obj)
173                 return NULL;
174
175         if (!strcmp(part, "elm.swallow.icon")) {
176                 img = elm_image_add(obj);
177                 if (!img)
178                         return NULL;
179
180                 snprintf(buf, sizeof(buf), "%s/%s", IMAGEDIR,
181                         MUSIC_IMAGE_FOLDER);
182                 elm_image_file_set(img, buf, "NULL");
183                 elm_image_no_scale_set(img, EINA_TRUE);
184                 return img;
185         }
186
187         return NULL;
188 }
189
190
191 Evas_Object *CFolderLayout::sm_CbGetGridSongItemContent(void *data, Evas_Object *obj, const char *part)
192 {
193         CSongInfo *sinfo = NULL;
194         SFolderItemInfo *itinfo = NULL;
195         char *path = NULL;
196         Evas_Object *img = NULL;
197         char buf[MAX_LENGTH];
198
199         if (!data || !obj)
200                 return NULL;
201
202         itinfo = (SFolderItemInfo *)data;
203         sinfo = itinfo->sinfo;
204
205         if (!strcmp(part, "elm.swallow.icon")) {
206                 img = elm_image_add(obj);
207                 if (!img)
208                         return NULL;
209
210                 path = sinfo->ThumbnailPath();
211                 if (!path) {
212                         snprintf(buf, sizeof(buf), "%s/%s", IMAGEDIR,
213                                 MUSIC_IMAGE_DEFAULT_THUMB_126);
214                         elm_image_file_set(img, buf, NULL);
215                         elm_image_no_scale_set(img, EINA_TRUE);
216                 }
217                 else {
218                         elm_image_file_set(img, path, NULL);
219                         elm_image_aspect_fixed_set(img, EINA_FALSE);
220                 }
221                 return img;
222         }
223         return NULL;
224 }
225
226
227 void CFolderLayout::sm_CbRemoveGridItem(void *data, Evas_Object *obj)
228 {
229         free(data);
230 }
231
232
233 Eina_Bool CFolderLayout::sm_CbFocusIdler(void *dt)
234 {
235         CFolderLayout *root = (CFolderLayout *)dt;
236
237         if (root)
238                 root->m_OnFocusIdler();
239
240         return ECORE_CALLBACK_CANCEL;
241 }
242
243
244 void CFolderLayout::m_OnFocusIdler(void)
245 {
246         Elm_Object_Item *it = NULL;
247
248         m->focus_idler = NULL;
249
250         if (m->depth == E_DEPTH_SONG) {
251                 it = elm_gengrid_first_item_get(m->grid);
252                 elm_object_item_focus_set(it, EINA_TRUE);
253         }
254         else {
255                 it = m_FindItemByInfo(m->it_infolist, m->c_finfo);
256                 if (it) {
257                         elm_gengrid_item_show(it, ELM_GENGRID_ITEM_SCROLLTO_IN);
258                         elm_object_item_focus_set(it, EINA_TRUE);
259                 }
260         }
261 }
262
263
264 void CFolderLayout::sm_CbCtxtUpdate(void *dt, enum EActionType type, int lid)
265 {
266         CFolderLayout *root = (CFolderLayout *)dt;
267         if (root) {
268                 root->m_OnCtxtUpdate(type, lid);
269         }
270 }
271
272 void CFolderLayout::m_OnCtxtUpdate(EActionType type, int lid)
273 {
274         Eina_List *list = NULL;
275         CSongInfo *sinfo = NULL;
276         EAddType mode;
277
278         if (!m->ctxtinfo || !m->ctxtinfo->context)
279                 return;
280
281         if (type == ACTION_TYPE_ADDNEXT)
282                 mode = ADD_TYPE_NEXT;
283         else
284                 mode = ADD_TYPE_END;
285
286         if (m->depth == E_DEPTH_SONG) {
287                 sinfo = (CSongInfo *)m->ctxtinfo->context;
288                 list = eina_list_append(list, sinfo);
289         }
290         else {
291                 m->mhandle->MediaGetList(LIST_TYPE_FOLDER_SONG,
292                         m->ctxtinfo->context, &list);
293                 sinfo = (CSongInfo *)eina_list_data_get(list);
294         }
295
296         if (type == ACTION_TYPE_ADDTO) {
297                 if (!m->mhandle->MediaAddsongsPlaylist(lid, list))
298                         _ERR(" Adding songs to playlist failed ");
299                 else
300                         _create_message_box(m->base, MUSIC_TEXT_ADDTO_MSG);
301
302                 return;
303         }
304
305         m->mhandle->UpdatePlaylist(list, mode);
306         eina_list_free(list);
307
308         if (type == ACTION_TYPE_PLAY) {
309                 m->mhandle->Stop();
310                 m->mhandle->SetCurrentSong(sinfo->Id());
311         }
312
313         _update_playback_view((EAddType)type, m->parent->Layout(), m->focused_item);
314 }
315
316 void CFolderLayout::sm_CbCtxtClose(void *dt)
317 {
318         CFolderLayout *root = (CFolderLayout *)dt;
319         if (root)
320                 root->m_OnCtxtClose();
321 }
322
323
324 void CFolderLayout::m_OnCtxtClose(void)
325 {
326         m->vmgr->PopView();
327         m->vmgr->PushView(MUSIC_BASE_VIEW, NULL);
328         elm_object_item_focus_set(m->focused_item, EINA_TRUE);
329 }
330
331
332 void CFolderLayout::sm_CbItemSelect(void *data, Elm_Object_Item *it, const char *emission, const char *source)
333 {
334         CFolderLayout *root = (CFolderLayout *)data;
335         if (root)
336                 root->m_OnItemSelect(it, emission, source);
337 }
338
339
340 void CFolderLayout::m_OnItemSelect(Elm_Object_Item *it, const char *emission, const char *source)
341 {
342         SFolderItemInfo *itinfo = NULL;
343         char *id = NULL;
344
345         if (!m)
346                 return;
347
348         itinfo = m_FindItemInfo(m->it_infolist, it);
349         if (!itinfo) {
350                 _ERR(" no item info found ");
351                 return;
352         }
353
354         if (m->depth == E_DEPTH_SONG) {
355                 if (!m->c_sinfo) {
356                         m->c_sinfo = new CSongInfo;
357                 }
358
359                 if (!m->c_sinfo->FlagCreate()) {
360                         m->c_sinfo->Create();
361                 }
362
363                 m->c_sinfo->Duplicate(itinfo->sinfo);
364         }
365         else {
366                 if (!m->c_finfo) {
367                         m->c_finfo = new CFolderInfo;
368                 }
369
370                 if (!m->c_finfo->FlagCreate()) {
371                         m->c_finfo->Create();
372                 }
373
374                 m->c_finfo->Duplicate(itinfo->finfo);
375         }
376
377         if (m->depth == E_DEPTH_SONG) {
378                 id = m->c_sinfo->Id();
379                 elm_gengrid_item_selected_set(it, EINA_FALSE);
380                 m_GotoPlayback(ADD_TYPE_FRESH, id);
381         }
382         else {
383                 m->depth = E_DEPTH_SONG;
384                 m_UpdateFolderGrid(false);
385                 m->focus_idler = ecore_idler_add(sm_CbFocusIdler, this);
386         }
387 }
388
389
390 SFolderItemInfo *CFolderLayout::m_FindItemInfo(Eina_List *list, Elm_Object_Item *item)
391 {
392         Eina_List *l = NULL;
393         SFolderItemInfo *itinfo = NULL;
394         void *obj = NULL;
395
396         if (!list || !item)
397                 return NULL;
398
399         EINA_LIST_FOREACH(list, l, obj) {
400                 itinfo = (SFolderItemInfo *)obj;
401                 if (itinfo->item == item)
402                         return itinfo;
403         }
404
405         return NULL;
406 }
407
408
409 int CFolderLayout::m_ConvertToMin(int milsec)
410 {
411         int min;
412         min = milsec / 60000;  /*milli seconds per minute*/
413
414         return min;
415 }
416
417
418 void CFolderLayout::m_RemoveFocusIdler(void)
419 {
420         if (!m->focus_idler)
421                 return;
422
423         ecore_idler_del(m->focus_idler);
424         m->focus_idler = NULL;
425 }
426
427
428 void CFolderLayout::m_GotoPlayback(int mode, char *id)
429 {
430         Eina_List *list = NULL;
431         Eina_List *l = NULL;
432         SFolderItemInfo *itinfo = NULL;
433         void *obj = NULL;
434         bool r;
435
436         if (!m->it_infolist || eina_list_count(m->it_infolist) == 0)
437                 return;
438
439         if (m->depth == E_DEPTH_SONG) {
440                 EINA_LIST_FOREACH(m->it_infolist, l, obj) {
441                         itinfo = (SFolderItemInfo *)obj;
442                         list = eina_list_append(list, itinfo->sinfo);
443                 }
444         }
445         else {
446                 r = m->mhandle->MediaGetList(LIST_TYPE_SONG, NULL, &list);
447                 if (r == false || eina_list_count(list) == 0)
448                         return;
449         }
450
451         m->mhandle->UpdatePlaylist(list, mode);
452         eina_list_free(list);
453
454         if (mode == ADD_TYPE_FRESH) {
455                 m->mhandle->Stop();
456                 if (id)   /* If want to play selected song */
457                         m->mhandle->SetCurrentSong(id);
458         }
459
460         _update_playback_view((EAddType)mode, CExtBaseLayout::Layout(), NULL);
461 }
462
463
464 Elm_Object_Item *CFolderLayout::m_FindItemByInfo(Eina_List *list, CFolderInfo *finfo)
465 {
466         Eina_List *l = NULL;
467         SFolderItemInfo *itinfo = NULL;
468         void *obj = NULL;
469         char *id = NULL;
470
471         if (!list || !finfo)
472                 return NULL;
473
474         EINA_LIST_FOREACH(list, l, obj) {
475                 itinfo = (SFolderItemInfo *)obj;
476                 id = itinfo->finfo->Id();
477                 if (!strcmp(id, finfo->Id()))
478                         return itinfo->item;
479         }
480
481         return NULL;
482 }
483
484
485 void CFolderLayout::m_SortFolderGrid(void)
486 {
487         int sortType;
488
489         const char *sortFuncId[] = {
490                 SORT_BY_NAME_AZ,
491                 SORT_BY_NAME_ZA,
492         };
493
494         if (!m->flist)
495                 return;
496
497         sortType = m->mhandle->SortType();
498         m->flist = CSort::Sort(m->flist, sortFuncId[sortType]);
499 }
500
501
502 void CFolderLayout::m_CreateFolderGrid(void)
503 {
504         Evas_Object *grid = NULL;
505         Elm_Gengrid_Item_Class *grid_item = NULL;
506
507         grid = elm_gengrid_add(Layout());
508         if (!grid)
509                 return;
510         evas_object_size_hint_weight_set(grid,
511                 EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
512         elm_gengrid_align_set(grid, 0, 0);
513         elm_object_part_content_set(Layout(), MUSIC_PART_FOLDER_GRID, grid);
514         Connect(grid, FOLDER_LAYOUT_GENGRID,
515                 TYPE_MOUSE_MOVE | TYPE_KEY_DOWN |
516                 TYPE_REALIZED | TYPE_UNREALIZED | TYPE_ACTIVATED);
517         elm_gengrid_item_size_set(grid,
518                 elm_config_scale_get() * GENGRID_ITEM_SIZE_W,
519                 elm_config_scale_get() * GENGRID_ITEM_SIZE_H);
520         m->grid = grid;
521
522         grid_item = elm_gengrid_item_class_new();
523         if (!grid_item) {
524                 evas_object_del(grid);
525                 _ERR(" elm_genlist_item_class_new failed ");
526                 return;
527         }
528         grid_item->item_style = MUSIC_STYLE_FOLDER_GRID;
529         grid_item->func.text_get = sm_CbGetGridItemText;
530         grid_item->func.content_get = sm_CbGetGridItemContent;
531         grid_item->func.state_get = NULL;
532         grid_item->func.del = sm_CbRemoveGridItem;
533         m->item_class = grid_item;
534
535         grid_item = elm_gengrid_item_class_new();
536         if (!grid_item) {
537                 elm_gengrid_item_class_free(m->item_class);
538                 m->item_class = NULL;
539                 evas_object_del(grid);
540                 _ERR(" elm_genlist_item_class_new failed ");
541                 return;
542         }
543         grid_item->item_style = MUSIC_STYLE_FOLDER_GRID;
544         grid_item->func.text_get = sm_CbGetGridSongItemText;
545         grid_item->func.content_get = sm_CbGetGridSongItemContent;
546         grid_item->func.state_get = NULL;
547         grid_item->func.del = sm_CbRemoveGridItem;
548         m->songitem_class = grid_item;
549
550         m_UpdateFolderGrid(false);
551 }
552
553
554 void CFolderLayout::m_EmptyFolderGrid(bool sort_flag)
555 {
556         if (m->grid)
557                 elm_gengrid_clear(m->grid);
558
559         if (!sort_flag) {
560                 eina_list_free(m->flist);
561                 m->flist = NULL;
562         }
563
564         eina_list_free(m->it_infolist);
565         m->it_infolist = NULL;
566 }
567
568
569 void CFolderLayout::m_UpdateFolderGrid(bool sort_flag)
570 {
571         bool r;
572         int ts, td, dur;
573         CFolderInfo *finfo = NULL;
574         CSongInfo *sinfo = NULL;
575         void *obj = NULL;
576         Eina_List *l = NULL;
577         struct SFolderItemInfo *itinfo = NULL;
578         Elm_Object_Item *item = NULL;
579         char buf[MAX_LENGTH];
580         int source_type;
581
582         if (!m->grid || !m->item_class)
583                 return;
584
585         /* Remove existing foldergrid and prepare afresh */
586         m_EmptyFolderGrid(sort_flag);
587
588         if (!sort_flag) {
589                 if (m->depth == E_DEPTH_SONG) {
590                         r = m->mhandle->MediaGetList(LIST_TYPE_FOLDER_SONG, m->c_finfo, &(m->flist));
591                         if (r == false ||
592                                 eina_list_count(m->flist) == 0) {
593                                 _ERR(" Fetching folder list  failed ");
594                                 return;
595                         }
596                 }
597                 else {
598                         r = m->mhandle->MediaGetList(LIST_TYPE_FOLDER,
599                                 NULL, &(m->flist));
600                         if (r == false ||
601                                 eina_list_count(m->flist) == 0) {
602                                 _ERR(" Fetching folder list  failed ");
603                                 SetEmptyStatus(true);
604                                 return;
605                         }
606                 }
607         }
608
609         m_SortFolderGrid();
610
611         ts = 0;
612         td = 0;
613         if (m->depth == E_DEPTH_SONG) {
614                 EINA_LIST_FOREACH(m->flist, l, obj) {
615                         sinfo = (CSongInfo *)obj;
616                         itinfo = (SFolderItemInfo *)calloc(1, sizeof(*itinfo));
617                         if (!itinfo)
618                                 return;
619                         itinfo->sinfo = sinfo;
620                         item = elm_gengrid_item_append(m->grid,
621                                 m->songitem_class, itinfo,
622                                 NULL, m);
623                         itinfo->item = item;
624                         m->it_infolist = eina_list_append(m->it_infolist,
625                                 itinfo);
626                         elm_object_part_text_set(Layout(),
627                                 MUSIC_PART_FOLDER_NAME,
628                                 m->c_finfo->Name());
629                         ts = ts + 1;
630                         dur = sinfo->Duration();
631                         td = td + dur;
632                 }
633         }
634         else {
635                 EINA_LIST_FOREACH(m->flist, l, obj) {
636                         finfo = (CFolderInfo *)obj;
637                         itinfo = (SFolderItemInfo *)calloc(1, sizeof(*itinfo));
638                         if (!itinfo)
639                                 return;
640                         itinfo->finfo = finfo;
641                         item = elm_gengrid_item_append(m->grid, m->item_class,
642                                 itinfo, NULL, NULL);
643                         itinfo->item = item;
644                         m->it_infolist = eina_list_append(m->it_infolist,
645                                 itinfo);
646                         source_type = m->mhandle->SourceType();
647                         elm_object_part_text_set(Layout(),
648                                 MUSIC_PART_FOLDER_NAME,
649                                 _(g_sourceTexts[source_type]));
650                         ts = ts + finfo->Count();
651                         td = td + finfo->Duration();
652                 }
653         }
654         snprintf(buf, sizeof(buf), "%d", ts);
655         elm_object_part_text_set(Layout(), MUSIC_PART_FOLDER_SONGCOUNT, buf);
656
657         snprintf(buf, sizeof(buf), "%d %s", m_ConvertToMin(td),
658                 _(MUSIC_TEXT_MIN));
659         elm_object_part_text_set(Layout(), MUSIC_PART_FOLDER_TIME, buf);
660 }
661
662
663 void CFolderLayout::m_CreateTopsection(void)
664 {
665         int i;
666         Evas_Object *btn;
667         char buf[MAX_LENGTH];
668         Evas_Object *img;
669         SBtnInfo btninfo[TOTAL_ADD_BTNS];
670
671         btninfo[BTN_PLAY].name = MUSIC_STR_PLAY;
672         btninfo[BTN_PLAY].part = MUSIC_PART_FOLDER_PLAYBTN;
673         btninfo[BTN_PLAY].style = MUSIC_STYLE_ADD_PLAY_BTN;
674         btninfo[BTN_PLAY].icon = MUSIC_IMAGE_ADD_PLAY;
675         btninfo[BTN_PLAY].type = FOLDER_LAYOUT_PLAY_BUTTON;
676
677         btninfo[BTN_NEXT].name = MUSIC_STR_ADDNEXT;
678         btninfo[BTN_NEXT].part = MUSIC_PART_FOLDER_NEXTBTN;
679         btninfo[BTN_NEXT].style = MUSIC_STYLE_ADD_NEXT_BTN;
680         btninfo[BTN_NEXT].icon = MUSIC_IMAGE_ADD_NEXT;
681         btninfo[BTN_NEXT].type = FOLDER_LAYOUT_NEXT_BUTTON;
682
683         btninfo[BTN_LAST].name = MUSIC_STR_ADDLAST;
684         btninfo[BTN_LAST].part = MUSIC_PART_FOLDER_LASTBTN;
685         btninfo[BTN_LAST].style = MUSIC_STYLE_ADD_LAST_BTN;
686         btninfo[BTN_LAST].icon = MUSIC_IMAGE_ADD_LAST;
687         btninfo[BTN_LAST].type = FOLDER_LAYOUT_LAST_BUTTON;
688
689         for (i = 0; i < TOTAL_ADD_BTNS; i++) {
690                 btn = elm_button_add(Layout());
691                 if (!btn)
692                         continue;
693
694                 evas_object_size_hint_weight_set(btn,
695                         EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
696                 elm_object_text_set(btn, _(btninfo[i].name));
697                 elm_object_style_set(btn, btninfo[i].style);
698
699                 Connect(btn, btninfo[i].type, TYPE_MOUSE_MOVE | TYPE_CLICKED);
700
701                 img = elm_image_add(btn);
702                 if (img) {
703                         snprintf(buf, sizeof(buf), "%s/%s", IMAGEDIR,
704                                 btninfo[i].icon);
705                         elm_image_file_set(img, buf, NULL);
706                         elm_object_part_content_set(btn,
707                                 MUSIC_PART_ELM_SWALLOWICON, img);
708                 }
709
710                 elm_object_part_content_set(Layout(), btninfo[i].part,
711                         btn);
712         }
713 }
714
715
716 bool CFolderLayout::Create(CLayoutMgr *mgr)
717 {
718         ASSERT(!m);
719
720         Evas_Object *base = NULL;
721         Evas_Object *win = NULL;
722         Evas_Object *layout = NULL;
723         CMusicController *mhandle = NULL;
724         CViewMgr *vmgr = NULL;
725
726         if (!mgr)
727                 return false;
728
729         m = new SFolderLayout;
730         if (!m) {
731                 _ERR(" calloc failed ");
732                 return false;
733         }
734
735         vmgr = CViewMgr::GetInstance();
736         if (!vmgr) {
737                 _ERR(" get view mgr failed ");
738                 delete m;
739                 m = NULL;
740                 return false;
741         }
742
743         base = mgr->Base();
744         if (!base) {
745                 _ERR(" get base failed ");
746                 delete m;
747                 m = NULL;
748                 return false;
749         }
750
751         win = vmgr->Window();
752         if (!win) {
753                 _ERR(" vimewmgr get win failed ");
754                 delete m;
755                 return false;
756         }
757
758         mhandle = CMusicController::GetInstance();
759         if (!mhandle) {
760                 _ERR(" music controller get music instance failed ");
761                 delete m;
762                 m = NULL;
763                 return false;
764         }
765
766         layout = _add_base(base, MUSIC_FOLDER_LAYOUT);
767         if (!layout) {
768                 _ERR(" get layout failed ");
769                 delete m;
770                 return false;
771         }
772
773         bool r = CExtBaseLayout::Create(layout);
774         if (!r) {
775                 _ERR(" CBaseLayout creation failed ");
776                 evas_object_del(layout);
777                 delete m;
778                 m = NULL;
779                 return false;
780         }
781
782         m->win = win;
783         m->base = base;
784         m->vmgr = vmgr;
785         m->mhandle = mhandle;
786         m->lmgr = mgr;
787         m->depth = E_DEPTH_FOLDER;
788         m->parent = this;
789
790         m_CreateTopsection();
791         m_CreateFolderGrid();
792
793         Connect(layout, FOLDER_LAYOUT, TYPE_KEY_DOWN);
794
795         SParcel parcel;
796         parcel.ctxtInfo = NULL;
797         parcel.updateType = E_LAYOUT_UPDATE;
798         parcel.layoutId = NULL;
799         parcel.keyEvent = NULL;
800         m->vmgr->UpdateView((const char *)MUSIC_BASE_VIEW, &parcel);
801
802         return true;
803 }
804
805
806 void CFolderLayout::Destroy(void)
807 {
808         ASSERT(m);
809
810         m_RemoveFocusIdler();
811         m_EmptyFolderGrid(false);
812         CExtBaseLayout::Destroy();
813         evas_object_del(Layout());
814
815         free(m->c_finfo);
816         if (m->c_sinfo && m->c_sinfo->FlagCreate())
817                 m->c_sinfo->Destroy();
818         delete m->c_sinfo;
819         free(m->ctxtinfo);
820         delete m;
821         m = NULL;
822 }
823
824
825 void CFolderLayout::t_OnShow(void)
826 {
827         ASSERT(m);
828         m->depth = E_DEPTH_FOLDER;
829         m_UpdateFolderGrid(false);
830         evas_object_show(Layout());
831 }
832
833
834 void CFolderLayout::Update(bool focusFlag)
835 {
836         ASSERT(m);
837
838         if (!focusFlag) {
839                 m_UpdateFolderGrid(true);
840                 return;
841         }
842
843         elm_object_focus_set(m->grid, EINA_TRUE);
844 }
845
846
847 void CFolderLayout::OnMouseMove(int id, Evas *e, Evas_Object *obj, Evas_Event_Mouse_Move *ev)
848 {
849         switch (id) {
850         case FOLDER_LAYOUT_GENGRID:
851                 {
852                         Elm_Object_Item *item;
853
854                         item = elm_gengrid_at_xy_item_get(obj, ev->cur.canvas.x,
855                                 ev->cur.canvas.y, NULL, NULL);
856                         if (!item)
857                                   return;
858
859                         if (!elm_object_item_focus_get(item))
860                                 elm_object_item_focus_set(item, EINA_TRUE);
861                 }
862                 break;
863
864         case FOLDER_LAYOUT_PLAY_BUTTON:
865         case FOLDER_LAYOUT_NEXT_BUTTON:
866         case FOLDER_LAYOUT_LAST_BUTTON:
867                 {
868                         if (!elm_object_focus_get(obj))
869                                 elm_object_focus_set(obj, EINA_TRUE);
870                 }
871                 break;
872
873         default:
874                 break;
875         }
876 }
877
878
879 void CFolderLayout::OnMouseClicked(int id, Evas_Object *obj)
880 {
881         switch (id) {
882         case FOLDER_LAYOUT_PLAY_BUTTON:
883                 m_GotoPlayback(ADD_TYPE_FRESH, NULL);
884                 break;
885
886         case FOLDER_LAYOUT_NEXT_BUTTON:
887                 m_GotoPlayback(ADD_TYPE_NEXT, NULL);
888                 break;
889
890         case FOLDER_LAYOUT_LAST_BUTTON:
891                 m_GotoPlayback(ADD_TYPE_END, NULL);
892                 break;
893
894         default:
895                 break;
896         }
897 }
898
899
900 void CFolderLayout::OnRealized(int id, Evas_Object *obj, Elm_Object_Item *item)
901 {
902         switch (id) {
903         case FOLDER_LAYOUT_GENGRID:
904                 elm_object_item_signal_callback_add(item,
905                         MUSIC_SIGNAL_BTN_CLICKED, MUSIC_BASE_VIEW,
906                         sm_CbItemSelect, this);
907                 break;
908
909         default:
910                 break;
911         }
912 }
913
914
915 void CFolderLayout::OnUnrealized(int id, Evas_Object *obj, Elm_Object_Item *item)
916 {
917         switch (id) {
918         case FOLDER_LAYOUT_GENGRID:
919                 elm_object_item_signal_callback_del((Elm_Object_Item *)item,
920                         MUSIC_SIGNAL_BTN_CLICKED, MUSIC_BASE_VIEW,
921                         sm_CbItemSelect);
922                 break;
923
924         default:
925                 break;
926         }
927 }
928
929
930 void CFolderLayout::OnKeyDown(int id, Evas *e, Evas_Object *obj, Evas_Event_Key_Down *ev)
931 {
932         switch (id) {
933         case FOLDER_LAYOUT:
934                 {
935                         if (!strcmp(ev->keyname, KEY_BACK)) {
936                                 if (m->depth == E_DEPTH_SONG) {
937                                         m->depth = E_DEPTH_FOLDER;
938                                         m_UpdateFolderGrid(false);
939                                         m_RemoveFocusIdler();
940                                         m->focus_idler = ecore_idler_add(sm_CbFocusIdler, this);
941                                 }
942                                 else {
943                                         SParcel parcel;
944                                         parcel.ctxtInfo = NULL;
945                                         parcel.updateType = E_FOCUS_UPDATE;
946                                         parcel.layoutId = NULL;
947                                         parcel.keyEvent = NULL;
948                                         m->vmgr->UpdateView((const char *)MUSIC_BASE_VIEW, &parcel);
949                                 }
950                         }
951                 }
952                 break;
953
954         case FOLDER_LAYOUT_GENGRID:
955                 {
956                         Elm_Object_Item *it = NULL;
957                         SContentInfo *ctxtinfo = NULL;
958                         SFolderItemInfo *itinfo = NULL;
959
960                         if (!obj)
961                                 return;
962
963                         if (strcmp(ev->keyname, KEY_MENU))
964                                 return;
965
966                         it = elm_object_focused_item_get(obj);
967                         if (!it) {
968                                 _ERR(" unable to get focused item ");
969                                 return;
970                         }
971                         m->focused_item = it;
972
973                         if (m->ctxtinfo) {
974                                 free(m->ctxtinfo);
975                                 m->ctxtinfo = NULL;
976                         }
977
978                         ctxtinfo = (SContentInfo *)calloc(1, sizeof(*ctxtinfo));
979                         if (!ctxtinfo)
980                                 return;
981
982                         itinfo = m_FindItemInfo(m->it_infolist, it);
983                         if (!itinfo) {
984                                 free(ctxtinfo);
985                                 return;
986                         }
987
988                         ctxtinfo->cbdata = this;
989                         ctxtinfo->update = sm_CbCtxtUpdate;
990                         ctxtinfo->close = sm_CbCtxtClose;
991                         if (m->depth == E_DEPTH_SONG) {
992                                 ctxtinfo->type = CONTEXT_TYPE_SONG;
993                                 ctxtinfo->context = itinfo->sinfo;
994                         }
995                         else {
996                                 ctxtinfo->type = CONTEXT_TYPE_FOLDER;
997                                 ctxtinfo->context = itinfo->finfo;
998                         }
999
1000                         m->ctxtinfo = ctxtinfo;
1001
1002                         SParcel parcel;
1003                         parcel.ctxtInfo = ctxtinfo;
1004                         if (!m->vmgr->PushView(MUSIC_CONTEXT_VIEW, &parcel))
1005                                 _ERR("viewmgr push view MUSIC_CONTEXT_VIEW failed");
1006                 }
1007                 break;
1008
1009         default:
1010                 break;
1011         }
1012 }
1013
1014
1015 void CFolderLayout::OnActivated(int id, Evas_Object *obj, Elm_Object_Item *item)
1016 {
1017         switch (id) {
1018         case FOLDER_LAYOUT_GENGRID:
1019                 m_OnItemSelect(item, NULL, NULL);
1020                 break;
1021
1022         default:
1023                 break;
1024         }
1025 }