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