2 * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #include <Elementary.h>
20 #include "AppCommon.h"
21 #include <InputHandler.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"
36 #include "ExtBaseLayout.h"
38 #include "category-layout.h"
39 #include "base-view.h"
41 #include "category-songs-layout.h"
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)
51 CATEGORY_LAYOUT_GENGRID,
52 CATEGORY_LAYOUT_PLAY_BUTTON,
53 CATEGORY_LAYOUT_NEXT_BUTTON,
54 CATEGORY_LAYOUT_LAST_BUTTON,
69 IDLER_TYPE_LAYOUT_UPDATE,
70 IDLER_TYPE_FOCUS_MOVE_BY_USER_INPUT
82 void(*cbHandleEmptyStatus)(void *cookie, bool emptyStatus);
86 struct SCategoryLayout {
89 Evas_Object *addBtns[TOTAL_ADD_BTNS];
90 Evas_Object *def_foc_btn;
94 Eina_List *it_infolist;
95 Ecore_Idler *focusIdler;
96 CMusicController *pMusicController;
100 CCategorySongsLayout *layoutCatSongs;
105 const char *focusBtnStr;
106 EFocusIderType idlerType;
108 const char *catSongLayoutId;
111 memset(this, 0, sizeof(SCategoryLayout));
119 Eina_Bool CCategoryLayout::sm_CbFocusIdler(void *dt)
121 CCategoryLayout *root = (CCategoryLayout *)dt;
124 root->m_OnFocusIdler();
126 return ECORE_CALLBACK_CANCEL;
130 void CCategoryLayout::m_OnFocusIdler(void)
132 m->focusIdler = NULL;
134 if (m->idlerType == IDLER_TYPE_LAYOUT_UPDATE) {
135 Elm_Object_Item *it = NULL;
136 SCatItemInfo *itinfo = NULL;
138 elm_object_tree_focus_allow_set(t.base, EINA_TRUE);
140 if (t.depth == E_DEPTH_CATEGORY) {
141 it = m_FindItemByInfo(m->it_infolist, t.c_catinfo);
143 itinfo = (SCatItemInfo *)eina_list_nth(m->it_infolist, 0);
146 elm_gengrid_item_show(it, ELM_GENGRID_ITEM_SCROLLTO_IN);
147 elm_object_item_focus_set(it, EINA_TRUE);
149 else if (t.depth == E_DEPTH_ALBUM)
150 elm_object_focus_set(m->def_foc_btn, EINA_TRUE);
153 Evas_Object *focus = NULL;
155 if (t.depth == E_DEPTH_CATEGORY) {
156 elm_gengrid_item_show(t.focused_item, ELM_GENGRID_ITEM_SCROLLTO_IN);
157 elm_object_item_focus_set(t.focused_item, EINA_TRUE);
159 else if (t.depth == E_DEPTH_ALBUM) {
160 if (!strcmp(m->focusBtnStr, MUSIC_FIRST_BTN))
161 focus = m->addBtns[ABTN_PLAY];
162 else if (!strcmp(m->focusBtnStr, MUSIC_SECOND_BTN))
163 focus = m->addBtns[ABTN_NEXT];
164 else // MUSIC_THIRD_BTN
165 focus = m->addBtns[ABTN_LAST];
167 elm_object_focus_set(focus, EINA_TRUE);
173 void CCategoryLayout::sm_CbEntrynameSet(void *dt, const char *name)
175 CCategoryLayout *root = (CCategoryLayout *)dt;
177 root->m_OnEntrynameSet(name);
181 void CCategoryLayout::m_OnEntrynameSet(const char *name)
183 Eina_List *idlist = NULL;
189 idlist = m_GetSelectedList(m->layoutCatSongs->CategorySongItemInfoList(), (int)ID_TYPE_MEDIA);
193 if (!strcmp(str, MUSIC_STR_EMPTY)) {
194 CCommonUI::CreateMsgBox(Layout(), MUSIC_TEXT_EMPTY_NAME);
199 if (m->pMusicController->MediaExistPlaylist(str)) {
200 CCommonUI::CreateMsgBox(Layout(), MUSIC_TEXT_INUSE_MSG);
205 if (!m->pMusicController->MediaInsertPlaylist(str, idlist)) {
206 _ERR("Playlist creation failed ");
212 t.depth = E_DEPTH_CATEGORY;
213 t_UpdateLayoutWithFocus();
216 memset(&parcel, 0, sizeof(SParcel));
217 parcel.updateType = E_DEPTH_UPDATE;
218 parcel.layoutId = MUSIC_CATEGORY_PLAYLISTS_SONGS_LAYOUT;
219 m->vmgr->UpdateView((const char *)MUSIC_BASE_VIEW, &parcel);
223 void CCategoryLayout::sm_CbCtxtUpdate(void *dt, enum EActionType type, int lid)
225 CCategoryLayout *root = (CCategoryLayout *)dt;
228 root->t_OnCtxtUpdate(type, lid);
232 void CCategoryLayout::t_OnCtxtUpdate(enum EActionType type, int lid)
234 Eina_List *list = NULL;
235 Eina_List *alist = NULL, *slist = NULL, *l = NULL, *sl = NULL;
236 CSongInfo *sinfo = NULL;
237 CAlbumInfo *alinfo = NULL;
241 if (!t.ctxtinfo || !t.ctxtinfo->context)
244 if (type == ACTION_TYPE_ADDNEXT)
245 mode = ADD_TYPE_NEXT;
249 if (t.depth == E_DEPTH_SONG) {
250 sinfo = (CSongInfo *)t.ctxtinfo->context;
251 list = eina_list_append(list, sinfo);
253 else if (t.depth == E_DEPTH_ALBUM) {
254 m->pMusicController->MediaGetList(LIST_TYPE_ALBUM_SONG,
255 t.ctxtinfo->context, &list);
256 sinfo = (CSongInfo *)eina_list_data_get(list);
259 alist = ((CCategoryInfo *)t.ctxtinfo->context)->AlbumList();
260 EINA_LIST_FOREACH(alist, l, obj) {
261 alinfo = (CAlbumInfo *)obj;
263 if (!m->pMusicController->MediaGetList(LIST_TYPE_ALBUM_SONG, (void *)alinfo, &slist)) {
264 _ERR(" Failed to get album songlist ");
267 EINA_LIST_FOREACH(slist, sl, obj) {
268 sinfo = (CSongInfo *)obj;
269 CSongInfo *dupSongInfo = new CSongInfo;
270 dupSongInfo->Create();
271 dupSongInfo->Duplicate(sinfo);
272 list = eina_list_append(list, dupSongInfo);
274 eina_list_free(slist);
276 sinfo = (CSongInfo *)eina_list_data_get(list);
279 if (type == ACTION_TYPE_ADDTO) {
280 if (!m->pMusicController->MediaAddsongsPlaylist(lid, list))
281 _ERR(" Adding songs to playlist failed ");
283 CCommonUI::CreateMsgBox(t.base, MUSIC_TEXT_ADDTO_MSG);
285 if (t.depth == E_DEPTH_CATEGORY) {
286 EINA_LIST_FREE(list, obj) {
287 sinfo = (CSongInfo *)obj;
296 m->pMusicController->UpdatePlaylist(list, mode);
297 if (type == ACTION_TYPE_PLAY) {
298 m->pMusicController->Stop();
299 m->pMusicController->SetCurrentSong(sinfo->Id());
302 if (t.depth == E_DEPTH_CATEGORY) {
303 EINA_LIST_FREE(list, obj) {
304 sinfo = (CSongInfo *)obj;
310 eina_list_free(list);
313 CCommonUI::UpdatePlaybackView((EAddType)type, Layout(), t.focused_item);
317 void CCategoryLayout::sm_CbCtxtClose(void *dt)
319 CCategoryLayout *root = (CCategoryLayout *)dt;
321 root->m_OnCtxtClose();
325 void CCategoryLayout::m_OnCtxtClose(void)
328 m->vmgr->PushView(MUSIC_BASE_VIEW, NULL);
329 elm_object_item_focus_set(t.focused_item, EINA_TRUE);
333 char *CCategoryLayout::sm_CbGetGridItemText(void *data, Evas_Object *obj, const char *part)
335 SCatItemInfo *itinfo = (SCatItemInfo *)data;
337 const char *txt = NULL;
338 char buf[MAX_LENGTH];
340 if (!itinfo || !obj || !part)
343 if (!strcmp(part, "elm.text")) {
344 if (itinfo->type == CAT_TYPE_PLAYLIST_NEW)
345 return strdup(_(MUSIC_TEXT_CREATE_PLAYLIST));
347 txt = itinfo->catinfo->Name();
351 else if (!strcmp(part, "elm.text1")) {
352 if (itinfo->type == CAT_TYPE_PLAYLIST_NEW) {
355 else if (itinfo->type == CAT_TYPE_PLAYLISTS) {
356 scount = itinfo->catinfo->SongCount();
357 snprintf(buf, sizeof(buf), "%d %s", scount, _("Songs"));
360 acount = itinfo->catinfo->AlbumCount();
361 scount = itinfo->catinfo->SongCount();
362 snprintf(buf, sizeof(buf), "%d %s, %d %s", acount,
363 _("Albums"), scount, _("Songs"));
372 char *CCategoryLayout::sm_CbGetGridAlbumItemText(void *data, Evas_Object *obj, const char *part)
374 SCatItemInfo *itinfo = (SCatItemInfo *)data;
375 CAlbumInfo *alinfo = NULL;
378 if (!itinfo || !obj || !part)
381 alinfo = itinfo->alinfo;
383 if (!strcmp(part, "elm.text")) {
384 txt = alinfo->Name();
388 else if (!strcmp(part, "elm.text1")) {
389 if (itinfo->type == CAT_TYPE_ARTIST)
390 txt = alinfo->Artist();
392 txt = alinfo->Genre();
401 Evas_Object *CCategoryLayout::sm_CbGetGridItemContent(void *data, Evas_Object *obj, const char *part)
403 SCatItemInfo *itinfo = (SCatItemInfo *)data;
404 CAlbumInfo *alinfo = NULL;
405 void *list_obj = NULL;
406 Eina_List *l = NULL, *alist = NULL;
407 Evas_Object *img = NULL;
409 char buf[MAX_LENGTH];
411 if (!itinfo || !obj || !part)
414 if (!itinfo->catinfo && itinfo->type != CAT_TYPE_PLAYLIST_NEW)
417 if (strcmp(part, "elm.swallow.icon"))
420 img = elm_image_add(obj);
426 if (itinfo->type == CAT_TYPE_ARTIST || itinfo->type == CAT_TYPE_GENRE) {
427 alist = itinfo->catinfo->AlbumList();
429 EINA_LIST_FOREACH(alist, l, list_obj) {
430 alinfo = (CAlbumInfo *)list_obj;
431 path = alinfo->ThumbnailPath();
437 else if (itinfo->type == CAT_TYPE_PLAYLISTS) {
438 path = itinfo->catinfo->ThumbnailPath();
442 if (itinfo->type == CAT_TYPE_PLAYLIST_NEW)
443 snprintf(buf, sizeof(buf), "%s/%s", IMAGEDIR,
444 MUSIC_IMAGE_CREATE_PLAYLIST);
446 snprintf(buf, sizeof(buf), "%s/%s", IMAGEDIR,
447 MUSIC_IMAGE_DEFAULT_THUMB_126);
448 elm_image_file_set(img, buf, NULL);
449 elm_image_no_scale_set(img, EINA_TRUE);
452 elm_image_file_set(img, path, NULL);
453 elm_image_aspect_fixed_set(img, EINA_FALSE);
460 Evas_Object *CCategoryLayout::sm_CbGetGridAlbumitemContent(void *data, Evas_Object *obj, const char *part)
462 SCatItemInfo *itinfo = (SCatItemInfo *)data;
463 CAlbumInfo *alinfo = NULL;
465 Evas_Object *img = NULL;
466 char buf[MAX_LENGTH];
468 if (!itinfo || !obj || !part)
471 alinfo = itinfo->alinfo;
473 if (strcmp(part, "elm.swallow.icon"))
476 img = elm_image_add(obj);
480 path = alinfo->ThumbnailPath();
482 snprintf(buf, sizeof(buf), "%s/%s", IMAGEDIR,
483 MUSIC_IMAGE_DEFAULT_THUMB_126);
484 elm_image_file_set(img, buf, NULL);
485 elm_image_no_scale_set(img, EINA_TRUE);
488 elm_image_file_set(img, path, NULL);
489 elm_image_aspect_fixed_set(img, EINA_FALSE);
496 void CCategoryLayout::sm_CbRemoveGridItem(void *data, Evas_Object *obj)
502 void CCategoryLayout::sm_CbItemSelect(void *data, Elm_Object_Item *it, const char *emission, const char *source)
504 CCategoryLayout *root = (CCategoryLayout *)data;
506 root->m_OnItemSelect(it, emission, source);
510 void CCategoryLayout::m_OnItemSelect(Elm_Object_Item *it, const char *emission, const char *source)
512 SCatItemInfo *itinfo = NULL;
514 itinfo = m_FindItemInfo(m->it_infolist, it);
516 _ERR(" no item info found ");
520 if (t.depth == E_DEPTH_ALBUM) {
522 t.c_alinfo = new CAlbumInfo;
525 if (!t.c_alinfo->FlagCreate()) {
526 t.c_alinfo->Create();
528 t.c_alinfo->Duplicate(itinfo->alinfo);
529 t.depth = E_DEPTH_SONG;
532 if (t.c_catinfo && t.c_catinfo->FlagCreate())
533 t.c_catinfo->Destroy();
538 t_HandleItemSelect(itinfo);
541 t_UpdateLayoutWithFocus();
545 int CCategoryLayout::m_ConvertToMin(int milsec)
549 min = milsec / 60000; /*milli seconds per minute*/
555 void CCategoryLayout::m_RemoveFocusIdler(void)
560 ecore_idler_del(m->focusIdler);
561 m->focusIdler = NULL;
565 Elm_Object_Item *CCategoryLayout::m_FindItemByInfo(Eina_List *list, void *info)
568 SCatItemInfo *itinfo = NULL;
575 EINA_LIST_FOREACH(list, l, obj) {
576 itinfo = (SCatItemInfo *)obj;
577 if (!itinfo->catinfo)
580 id = itinfo->catinfo->CategoryId();
581 if (id == ((CCategoryInfo *)info)->CategoryId())
589 CCategoryLayout::SCatItemInfo *CCategoryLayout::m_FindItemInfo(Eina_List *list, Elm_Object_Item *item)
592 SCatItemInfo *itinfo = NULL;
598 EINA_LIST_FOREACH(list, l, obj) {
599 itinfo = (SCatItemInfo *)obj;
600 if (itinfo->item == item)
608 void CCategoryLayout::m_GotoPlayback(int mode, char *id)
610 if (!m->it_infolist || eina_list_count(m->it_infolist) == 0) {
611 CCommonUI::CreateMsgBox(Layout(), MUSIC_TEXT_NO_SONGS);
612 _ERR(" No songs for playback ");
616 if (t.depth == E_DEPTH_ALBUM)
617 m_AddAlbumsToPlayback(mode);
618 else if (t.depth == E_DEPTH_SONG ||
619 t.depth == E_DEPTH_SHOW_LIST)
620 m_AddSongsToPlayback(mode);
624 if (mode == ADD_TYPE_FRESH) {
625 m->pMusicController->Stop();
626 if (id) /* If want to play selected song */
627 m->pMusicController->SetCurrentSong(id);
630 CCommonUI::UpdatePlaybackView((EAddType)mode, Layout(), NULL);
634 Eina_List *CCategoryLayout::m_GetSelectedList(Eina_List *infolist, int type)
636 Eina_List *idlist = NULL, *l = NULL;
637 CCategorySongsLayout::SCategorySongsItemsInfo *itinfo = NULL;
640 EIdType eType = (EIdType)type;
646 EINA_LIST_FOREACH(infolist, l, obj) {
647 itinfo = (CCategorySongsLayout::SCategorySongsItemsInfo *)obj;
648 if (!itinfo->check_status)
651 if (eType == ID_TYPE_MEDIA) {
652 id = itinfo->sinfo->Id();
654 idlist = eina_list_append(idlist, id);
657 idlist = eina_list_append(idlist,
666 void CCategoryLayout::m_AddAlbumsToPlayback(int mode)
668 Eina_List *l = NULL, *sl = NULL;
669 Eina_List *slist = NULL;
670 Eina_List *list = NULL;
671 CSongInfo *sinfo = NULL;
672 SCatItemInfo *itinfo = NULL;
674 Eina_List *infolist = m->it_infolist;
675 CMusicController *pMusicController = m->pMusicController;
678 EINA_LIST_FOREACH(infolist, l, obj) {
679 itinfo = (SCatItemInfo *)obj;
681 if (!pMusicController->MediaGetList(LIST_TYPE_ALBUM_SONG, itinfo->alinfo, &slist)) {
682 _ERR(" Failed to get album songlist ");
686 EINA_LIST_FOREACH(slist, sl, obj) {
687 sinfo = (CSongInfo *)obj;
688 CSongInfo *dupSongInfo = new CSongInfo;
689 dupSongInfo->Create();
690 dupSongInfo->Duplicate(sinfo);
691 list = eina_list_append(list, dupSongInfo);
694 eina_list_free(slist);
697 pMusicController->UpdatePlaylist(list, mode);
698 EINA_LIST_FREE(list, obj) {
699 sinfo = (CSongInfo *)obj;
706 void CCategoryLayout::m_AddSongsToPlayback(int mode)
709 Eina_List *list = NULL;
710 struct SCatItemInfo *itinfo = NULL;
712 Eina_List *infolist = m->it_infolist;
713 CMusicController *pMusicController = m->pMusicController;
716 EINA_LIST_FOREACH(infolist, l, obj) {
717 itinfo = (SCatItemInfo *)obj;
718 list = eina_list_append(list, itinfo->sinfo);
721 pMusicController->UpdatePlaylist(list, mode);
722 eina_list_free(list);
726 Evas_Object *CCategoryLayout::m_AddGrid(void)
728 Evas_Object *grid = NULL;
730 grid = elm_gengrid_add(Layout());
734 evas_object_size_hint_weight_set(grid,
735 EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
736 elm_gengrid_align_set(grid, 0, 0);
738 Connect(grid, CATEGORY_LAYOUT_GENGRID, TYPE_MOUSE_MOVE | TYPE_KEY_DOWN | TYPE_REALIZED | TYPE_UNREALIZED | TYPE_ACTIVATED);
740 elm_gengrid_item_size_set(grid,
741 elm_config_scale_get() * GENGRID_ITEM_SIZE_W,
742 elm_config_scale_get() * GENGRID_ITEM_SIZE_H);
748 void CCategoryLayout::m_AddCategoryItem(Elm_Gengrid_Item_Class *grid_item, ECategoryType type, void *info)
750 SCatItemInfo *itinfo = NULL;
751 Elm_Object_Item *item = NULL;
756 itinfo = (SCatItemInfo *)calloc(1, sizeof(*itinfo));
760 itinfo->catinfo = (CCategoryInfo *)info;
762 item = elm_gengrid_item_append(t.grid,
763 grid_item, itinfo, NULL, m);
765 m->it_infolist = eina_list_append(m->it_infolist,
770 void CCategoryLayout::m_AddButtons(void)
773 Evas_Object *img = NULL;
774 char buf[MAX_LENGTH];
775 SBtnInfo btninfo[TOTAL_ADD_BTNS];
777 btninfo[ABTN_PLAY].name = MUSIC_STR_PLAY;
778 btninfo[ABTN_PLAY].part = MUSIC_PART_CATEGORY_PLAYBTN;
779 btninfo[ABTN_PLAY].style = MUSIC_STYLE_ADD_PLAY_BTN;
780 btninfo[ABTN_PLAY].icon = MUSIC_IMAGE_ADD_PLAY;
781 btninfo[ABTN_PLAY].type = CATEGORY_LAYOUT_PLAY_BUTTON;
783 btninfo[ABTN_NEXT].name = MUSIC_STR_ADDNEXT;
784 btninfo[ABTN_NEXT].part = MUSIC_PART_CATEGORY_NEXTBTN;
785 btninfo[ABTN_NEXT].style = MUSIC_STYLE_ADD_NEXT_BTN;
786 btninfo[ABTN_NEXT].icon = MUSIC_IMAGE_ADD_NEXT;
787 btninfo[ABTN_NEXT].type = CATEGORY_LAYOUT_NEXT_BUTTON;
789 btninfo[ABTN_LAST].name = MUSIC_STR_ADDLAST;
790 btninfo[ABTN_LAST].part = MUSIC_PART_CATEGORY_LASTBTN;
791 btninfo[ABTN_LAST].style = MUSIC_STYLE_ADD_LAST_BTN;
792 btninfo[ABTN_LAST].icon = MUSIC_IMAGE_ADD_LAST;
793 btninfo[ABTN_LAST].type = CATEGORY_LAYOUT_LAST_BUTTON;
795 if (t.depth == E_DEPTH_SHOW_LIST) {
796 btninfo[ABTN_PLAY].part = MUSIC_PART_ALBUM_PLAYBTN;
797 btninfo[ABTN_NEXT].part = MUSIC_PART_ALBUM_NEXTBTN;
798 btninfo[ABTN_LAST].part = MUSIC_PART_ALBUM_LASTBTN;
801 for (i = 0; i < TOTAL_ADD_BTNS; i++) {
802 m->addBtns[i] = elm_button_add(Layout());
806 evas_object_size_hint_weight_set(m->addBtns[i],
807 EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
808 elm_object_text_set(m->addBtns[i], _(btninfo[i].name));
809 elm_object_style_set(m->addBtns[i], btninfo[i].style);
811 Connect(m->addBtns[i], btninfo[i].type, TYPE_CLICKED | TYPE_MOUSE_MOVE | TYPE_KEY_DOWN);
813 img = elm_image_add(m->addBtns[i]);
815 snprintf(buf, sizeof(buf), "%s/%s", IMAGEDIR,
817 elm_image_file_set(img, buf, NULL);
818 elm_object_part_content_set(m->addBtns[i],
819 MUSIC_PART_ELM_SWALLOWICON, img);
822 elm_object_part_content_set(Layout(), btninfo[i].part, m->addBtns[i]);
825 elm_object_focus_set(m->addBtns[ABTN_PLAY], EINA_TRUE);
826 m->def_foc_btn = m->addBtns[ABTN_PLAY];
830 void CCategoryLayout::m_CreateAlbumgrid(void)
832 CAlbumInfo *alinfo = NULL;
835 SCatItemInfo *itinfo = NULL;
836 Elm_Object_Item *item = NULL;
837 char buf[MAX_LENGTH];
838 Elm_Gengrid_Item_Class *grid_item = NULL;
841 t.grid = m_AddGrid();
846 grid_item = elm_gengrid_item_class_new();
848 evas_object_del(t.grid);
849 _ERR(" elm_genlist_item_class_new failed ");
852 grid_item->item_style = MUSIC_STYLE_CATEGORY_GRID;
853 grid_item->func.text_get = sm_CbGetGridAlbumItemText;
854 grid_item->func.content_get = sm_CbGetGridAlbumitemContent;
855 grid_item->func.state_get = NULL;
856 grid_item->func.del = sm_CbRemoveGridItem;
858 m->alblist = t.c_catinfo->AlbumList();
859 if (!m->alblist || eina_list_count(m->alblist) == 0) {
860 _ERR(" Fetching album list failed ");
861 evas_object_del(t.grid);
862 elm_gengrid_item_class_free(grid_item);
867 EINA_LIST_FOREACH(m->alblist, l, obj) {
868 alinfo = (CAlbumInfo *)obj;
869 itinfo = (SCatItemInfo *)calloc(1, sizeof(*itinfo));
872 itinfo->alinfo = alinfo;
873 item = elm_gengrid_item_append(t.grid,
874 grid_item, itinfo, NULL, m);
876 m->it_infolist = eina_list_append(m->it_infolist,
879 t.focused_item = item;
882 elm_gengrid_item_class_free(grid_item);
884 elm_object_part_text_set(Layout(),
885 MUSIC_PART_CATEGORY_NAME,
886 t.c_catinfo->Name());
887 snprintf(buf, sizeof(buf), "%d",
888 t.c_catinfo->AlbumCount());
889 elm_object_part_text_set(Layout(),
890 MUSIC_PART_CATEGORY_ALBUMCOUNT, buf);
891 snprintf(buf, sizeof(buf), "%d",
892 t.c_catinfo->SongCount());
893 elm_object_part_text_set(Layout(),
894 MUSIC_PART_CATEGORY_SONGCOUNT, buf);
895 elm_object_part_content_set(Layout(),
896 MUSIC_PART_CATEGORY_ALBUM_GRID, t.grid);
900 void CCategoryLayout::m_CreateCatgrid(bool sort_flag)
904 Elm_Gengrid_Item_Class *grid_item = NULL;
907 t.grid = m_AddGrid();
912 grid_item = elm_gengrid_item_class_new();
914 evas_object_del(t.grid);
915 _ERR(" elm_genlist_item_class_new failed ");
918 grid_item->item_style = MUSIC_STYLE_CATEGORY_GRID;
919 grid_item->func.text_get = sm_CbGetGridItemText;
920 grid_item->func.content_get = sm_CbGetGridItemContent;
921 grid_item->func.state_get = NULL;
922 grid_item->func.del = sm_CbRemoveGridItem;
925 if (!t_GetMediaList(&m->catlist)) {
926 if (t_CategoryType() != CAT_TYPE_PLAYLISTS) {
927 _ERR(" Fetching list failed ");
928 SetEmptyStatus(true);
929 elm_gengrid_item_class_free(grid_item);
936 if (t_CategoryType() == CAT_TYPE_PLAYLISTS)
937 m_AddCategoryItem(grid_item, CAT_TYPE_PLAYLIST_NEW, NULL);
939 EINA_LIST_FOREACH(m->catlist, l, info)
940 m_AddCategoryItem(grid_item, t_CategoryType(), info);
942 elm_gengrid_item_class_free(grid_item);
944 elm_object_part_content_set(Layout(),
945 MUSIC_PART_CATEGORY_GRID, t.grid);
949 void CCategoryLayout::m_SortCatgrid(void)
951 const char *sortFuncType[] = {
961 sortType = CInfo::SortType();
963 m->catlist = CSortMgr::Sort(m->catlist, sortFuncType[sortType]);
967 void CCategoryLayout::m_EmptyLayout(bool sort_flag)
970 elm_gengrid_clear(t.grid);
975 eina_list_free(m->catlist);
979 // This value is just referenced from CCategoryInfo.
980 // So should not freed here.
984 eina_list_free(m->songlist);
988 eina_list_free(m->it_infolist);
989 m->it_infolist = NULL;
991 m->total_duration = 0;
995 for (i = 0; i < TOTAL_ADD_BTNS; i++) {
997 evas_object_del(m->addBtns[i]);
998 m->addBtns[i] = NULL;
1003 void CCategoryLayout::m_ShowCategorySongs(void)
1005 elm_object_part_content_unset(t.base, MUSIC_PART_CONTENT);
1007 bool emptyStatus = m->layoutCatSongs->EmptyStatus();
1009 if (emptyStatus == false) {
1010 elm_object_part_content_set(t.base, MUSIC_PART_CONTENT, m->layoutCatSongs->Layout());
1011 m->lmgr->Show(m->catSongLayoutId);
1014 if (m->callback.cbHandleEmptyStatus != NULL) {
1015 m->callback.cbHandleEmptyStatus(m->callback.cookie, emptyStatus);
1020 const char *CCategoryLayout::m_CategorySongLayoutId(void)
1022 const char *layoutId = NULL;
1024 if (!strcmp(LayoutId(), MUSIC_CATEGORY_ARTIST_LAYOUT))
1025 layoutId = MUSIC_CATEGORY_ARTIST_SONGS_LAYOUT;
1026 else if (!strcmp(LayoutId(), MUSIC_CATEGORY_GENRE_LAYOUT))
1027 layoutId = MUSIC_CATEGORY_GENRE_SONGS_LAYOUT;
1028 else if (!strcmp(LayoutId(), MUSIC_CATEGORY_PLAYLISTS_LAYOUT))
1029 layoutId = MUSIC_CATEGORY_PLAYLISTS_SONGS_LAYOUT;
1035 bool CCategoryLayout::t_SetEdje(const char *szLayout)
1038 if (!elm_layout_file_set(Layout(), EDJEFILE, szLayout)) {
1039 _ERR(" elm szLayout file set failed ");
1046 void CCategoryLayout::t_UpdateLayout(bool sort_flag)
1048 /* Remove existing grid and prepare afresh */
1049 m_EmptyLayout(sort_flag);
1052 memset(&parcel, 0, sizeof(SParcel));
1054 if (t.depth == E_DEPTH_SONG) {
1055 m->layoutCatSongs->SetParameter(CCategorySongsLayout::DEPTH_SONG_LIST, (CCategorySongsLayout::ESelectType)t.sel_type, t.c_catinfo, t.c_alinfo);
1056 m_ShowCategorySongs();
1058 parcel.updateType = E_LAYOUT_UPDATE;
1059 parcel.layoutId = MUSIC_CATEGORY_SONGS_LAYOUT;
1060 m->vmgr->UpdateView((const char *)MUSIC_BASE_VIEW, &parcel);
1062 else if (t.depth == E_DEPTH_SHOW_LIST) {
1063 m->layoutCatSongs->SetParameter(CCategorySongsLayout::DEPTH_SHOW_LIST, (CCategorySongsLayout::ESelectType)t.sel_type, t.c_catinfo, t.c_alinfo);
1064 m_ShowCategorySongs();
1066 parcel.updateType = E_LAYOUT_UPDATE;
1067 parcel.layoutId = MUSIC_CATEGORY_SONGS_LAYOUT;
1068 m->vmgr->UpdateView((const char *)MUSIC_BASE_VIEW, &parcel);
1070 else if (t.depth == E_DEPTH_ALBUM) {
1071 if (!t_SetEdje(MUSIC_CATEGORY_ALBUM_LAYOUT)) {
1072 _ERR(" get layout failed ");
1076 m_CreateAlbumgrid();
1078 parcel.updateType = E_LAYOUT_UPDATE;
1079 parcel.layoutId = MUSIC_CATEGORY_ALBUM_LAYOUT;
1080 m->vmgr->UpdateView((const char *)MUSIC_BASE_VIEW, &parcel);
1082 else if (t.depth == E_DEPTH_SELECT_LIST) {
1083 m->layoutCatSongs->SetParameter(CCategorySongsLayout::DEPTH_SELECT_LIST, (CCategorySongsLayout::ESelectType)t.sel_type, t.c_catinfo, t.c_alinfo);
1084 m_ShowCategorySongs();
1086 parcel.updateType = E_LAYOUT_UPDATE;
1087 parcel.layoutId = MUSIC_CATEGORY_SELECTLIST_LAYOUT;
1088 m->vmgr->UpdateView((const char *)MUSIC_BASE_VIEW, &parcel);
1090 else { // E_DEPTH_CATEGORY
1091 if (!t_SetEdje(MUSIC_CATEGORY_LAYOUT)) {
1092 _ERR(" get layout failed ");
1095 m_CreateCatgrid(sort_flag);
1097 parcel.updateType = E_LAYOUT_UPDATE;
1098 parcel.layoutId = MUSIC_CATEGORY_LAYOUT;
1099 m->vmgr->UpdateView((const char *)MUSIC_BASE_VIEW, &parcel);
1104 void CCategoryLayout::t_UpdateLayoutWithFocus(void)
1106 bool needFocusIdler = false;
1108 if (t.depth == E_DEPTH_ALBUM || t.depth == E_DEPTH_CATEGORY)
1109 needFocusIdler = true;
1112 elm_object_tree_focus_allow_set(t.base, EINA_FALSE);
1114 t_UpdateLayout(false);
1116 if (needFocusIdler) {
1117 m_RemoveFocusIdler();
1118 m->idlerType = IDLER_TYPE_LAYOUT_UPDATE;
1119 m->focusIdler = ecore_idler_add(sm_CbFocusIdler, this);
1124 bool CCategoryLayout::Create(CLayoutMgr *mgr)
1130 Evas_Object *base = NULL;
1131 Evas_Object *win = NULL;
1132 Evas_Object *layout = NULL;
1133 CMusicController *pMusicController = NULL;
1134 CViewMgr *vmgr = NULL;
1135 CEntryPopup *popup = NULL;
1136 CCategorySongsLayout *layoutCatSongs = NULL;
1137 const char *catSongLayoutId = NULL;
1139 _CHECK(m = new SCategoryLayout)
1140 _CHECK(vmgr = CViewMgr::GetInstance())
1141 _CHECK(base = mgr->Base())
1142 _CHECK(win = vmgr->Window())
1143 _CHECK(pMusicController = CMusicController::GetInstance())
1144 _CHECK(layout = elm_layout_add(base))
1145 _CHECK(CExtBaseLayout::Create(layout))
1146 _CHECK(popup = new CEntryPopup)
1147 _CHECK(catSongLayoutId = m_CategorySongLayoutId())
1148 _CHECK(layoutCatSongs = new CCategorySongsLayout(catSongLayoutId))
1149 _CHECK(layoutCatSongs->Create(mgr, this))
1150 _CHECK(mgr->AddLayout(layoutCatSongs))
1153 memset(&t, 0, sizeof(SCategoryLayoutProtected));
1158 m->pMusicController = pMusicController;
1160 t.depth = E_DEPTH_CATEGORY;
1161 m->callback.cbHandleEmptyStatus = NULL;
1162 m->callback.cookie = NULL;
1164 m->catSongLayoutId = catSongLayoutId;
1165 m->layoutCatSongs = layoutCatSongs;
1167 t_UpdateLayout(false);
1169 Connect(Layout(), CATEGORY_LAYOUT, TYPE_KEY_DOWN);
1172 _CHECK_FAIL{ mgr->RemoveLayout(layoutCatSongs); }
1173 _CHECK_FAIL{ m->layoutCatSongs->Destroy(); }
1174 _CHECK_FAIL{ delete layoutCatSongs; }
1176 _CHECK_FAIL{ delete popup; }
1177 _CHECK_FAIL{ CExtBaseLayout::Destroy(); }
1178 _CHECK_FAIL{ evas_object_del(layout); }
1183 _CHECK_FAIL{ delete m; m = NULL; }
1184 } _CREATE_END_AND_CATCH{ return false; }
1190 void CCategoryLayout::Destroy(void)
1194 Disconnect(Layout());
1196 m->lmgr->RemoveLayout(m->layoutCatSongs);
1197 m->layoutCatSongs->Destroy();
1198 delete m->layoutCatSongs;
1200 if (t.epopup->FlagCreate())
1201 t.epopup->Destroy();
1204 m_RemoveFocusIdler();
1205 m_EmptyLayout(false);
1207 if (t.c_catinfo && t.c_catinfo->FlagCreate())
1208 t.c_catinfo->Destroy();
1211 if (t.c_alinfo && t.c_alinfo->FlagCreate())
1212 t.c_alinfo->Destroy();
1215 CExtBaseLayout::Destroy();
1216 evas_object_del(Layout());
1223 void CCategoryLayout::t_OnShow(void)
1227 t.depth = E_DEPTH_CATEGORY;
1228 t_UpdateLayout(false);
1229 evas_object_show(Layout());
1233 void CCategoryLayout::Update(bool focusFlag)
1238 if (t.depth != E_DEPTH_CATEGORY)
1240 t_UpdateLayout(true);
1244 elm_object_focus_set(t.grid, EINA_TRUE);
1248 void CCategoryLayout::CreateEntryPopup(void)
1252 if (t.epopup->FlagCreate())
1253 t.epopup->Destroy();
1255 t.epopup->Create(t.base, MUSIC_STR_EMPTY, sm_CbEntrynameSet, this);
1259 void CCategoryLayout::SetEmptyStatusHandleCallback(void(*handleEmptyStatusCb)(void *cookie, bool emptyStatus), void *cookie)
1263 m->callback.cbHandleEmptyStatus = handleEmptyStatusCb;
1264 m->callback.cookie = cookie;
1268 void CCategoryLayout::SetFocus(const char *btnStr)
1272 m->idlerType = IDLER_TYPE_FOCUS_MOVE_BY_USER_INPUT;
1273 m->focusBtnStr = btnStr;
1274 m->focusIdler = ecore_idler_add(sm_CbFocusIdler, this);
1278 void CCategoryLayout::OnKeyDown(int id, Evas *e, Evas_Object *obj, Evas_Event_Key_Down *ev)
1281 case CATEGORY_LAYOUT:
1284 Eina_List *alist = NULL;
1286 if (!strcmp(ev->keyname, KEY_BACK) ||
1287 !strcmp(ev->keyname, KEY_BACK_REMOTE)) {
1288 if (t.depth == E_DEPTH_CATEGORY) {
1290 memset(&parcel, 0, sizeof(SParcel));
1291 parcel.updateType = E_FOCUS_UPDATE;
1292 m->vmgr->UpdateView((const char *)MUSIC_BASE_VIEW, &parcel);
1295 else if (t.depth == E_DEPTH_ALBUM) {
1296 t.depth = E_DEPTH_CATEGORY;
1298 else if (t.depth == E_DEPTH_SELECT_LIST) {
1299 t.depth = E_DEPTH_CATEGORY;
1301 else if (t.depth == E_DEPTH_SHOW_LIST) {
1302 t.depth = E_DEPTH_CATEGORY;
1304 else if (t.depth == E_DEPTH_SONG) {
1306 alist = t.c_catinfo->AlbumList();
1308 count = eina_list_count(alist);
1310 t.depth = E_DEPTH_CATEGORY;
1312 t.depth = E_DEPTH_ALBUM;
1315 t_UpdateLayoutWithFocus();
1320 case CATEGORY_LAYOUT_GENGRID:
1322 Elm_Object_Item *it = NULL;
1323 SContentInfo *ctxtinfo = NULL;
1324 SCatItemInfo *itinfo = NULL;
1329 it = elm_object_focused_item_get(obj);
1331 _ERR(" unable to get focused item ");
1335 t.focused_item = it;
1337 if ((!strcmp(ev->keyname, KEY_MENU) ||
1338 !strcmp(ev->keyname, KEY_MENU_REMOTE)) &&
1339 t.depth != E_DEPTH_SELECT_LIST &&
1340 t.depth != E_DEPTH_SHOW_LIST) {
1346 ctxtinfo = (SContentInfo *)calloc(1, sizeof(*ctxtinfo));
1350 itinfo = m_FindItemInfo(m->it_infolist, it);
1351 if (!itinfo || itinfo->type == CAT_TYPE_PLAYLIST_NEW) {
1356 ctxtinfo->cbdata = this;
1357 ctxtinfo->update = sm_CbCtxtUpdate;
1358 ctxtinfo->close = sm_CbCtxtClose;
1359 if (t.depth == E_DEPTH_SONG) {
1360 ctxtinfo->type = CONTEXT_TYPE_SONG;
1361 ctxtinfo->context = itinfo->sinfo;
1363 else if (t.depth == E_DEPTH_ALBUM) {
1364 ctxtinfo->type = CONTEXT_TYPE_ALBUM;
1365 ctxtinfo->context = itinfo->alinfo;
1368 ctxtinfo->type = t_ContextType();
1369 ctxtinfo->context = itinfo->catinfo;
1372 t.ctxtinfo = ctxtinfo;
1375 memset(&parcel, 0, sizeof(SParcel));
1376 parcel.ctxtInfo = ctxtinfo;
1377 if (!m->vmgr->PushView(MUSIC_CONTEXT_VIEW, &parcel))
1378 _ERR("viewmgr push view MUSIC_CONTEXT_VIEW failed");
1383 case CATEGORY_LAYOUT_PLAY_BUTTON:
1384 case CATEGORY_LAYOUT_NEXT_BUTTON:
1385 case CATEGORY_LAYOUT_LAST_BUTTON:
1386 if (!strcmp(ev->keyname, KEY_UP)) {
1387 const char *btnText = NULL;
1389 if (id == CATEGORY_LAYOUT_PLAY_BUTTON)
1390 btnText = MUSIC_FIRST_BTN;
1391 else if (id == CATEGORY_LAYOUT_NEXT_BUTTON)
1392 btnText = MUSIC_SECOND_BTN;
1393 else //CATEGORY_LAYOUT_LAST_BUTTON
1394 btnText = MUSIC_THIRD_BTN;
1397 memset(&parcel, 0, sizeof(SParcel));
1398 parcel.updateType = E_FOCUS_UPDATE;
1399 parcel.keyEvent = KEY_UP;
1400 parcel.focusedBtn = btnText;
1401 m->vmgr->UpdateView((const char *)MUSIC_BASE_VIEW, &parcel);
1411 void CCategoryLayout::OnMouseClicked(int id, Evas_Object *obj)
1415 case CATEGORY_LAYOUT_PLAY_BUTTON:
1416 m_GotoPlayback(ADD_TYPE_FRESH, NULL);
1419 case CATEGORY_LAYOUT_NEXT_BUTTON:
1420 m_GotoPlayback(ADD_TYPE_NEXT, NULL);
1423 case CATEGORY_LAYOUT_LAST_BUTTON:
1424 m_GotoPlayback(ADD_TYPE_END, NULL);
1433 void CCategoryLayout::OnMouseMove(int id, Evas *e, Evas_Object *obj, Evas_Event_Mouse_Move *ev)
1436 case CATEGORY_LAYOUT_PLAY_BUTTON:
1437 case CATEGORY_LAYOUT_NEXT_BUTTON:
1438 case CATEGORY_LAYOUT_LAST_BUTTON:
1440 if (!elm_object_focus_get(obj))
1441 elm_object_focus_set(obj, EINA_TRUE);
1445 case CATEGORY_LAYOUT_GENGRID:
1447 Elm_Object_Item *item;
1452 item = elm_gengrid_at_xy_item_get(obj, ev->cur.canvas.x,
1453 ev->cur.canvas.y, NULL, NULL);
1457 if (!elm_object_item_focus_get(item))
1458 elm_object_item_focus_set(item, EINA_TRUE);
1460 t.focused_item = item;
1470 void CCategoryLayout::OnRealized(int id, Evas_Object *obj, Elm_Object_Item *item)
1473 case CATEGORY_LAYOUT_GENGRID:
1474 elm_object_item_signal_callback_add(item,
1475 MUSIC_SIGNAL_BTN_CLICKED, MUSIC_BASE_VIEW,
1476 sm_CbItemSelect, this);
1485 void CCategoryLayout::OnUnrealized(int id, Evas_Object *obj, Elm_Object_Item *item)
1488 case CATEGORY_LAYOUT_GENGRID:
1489 elm_object_item_signal_callback_del(item,
1490 MUSIC_SIGNAL_BTN_CLICKED, MUSIC_BASE_VIEW,
1500 void CCategoryLayout::OnActivated(int id, Evas_Object *obj, Elm_Object_Item *item)
1503 case CATEGORY_LAYOUT_GENGRID:
1504 m_OnItemSelect(item, NULL, NULL);