/* * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved * * Licensed under the Apache License, Version 2.0 (the License); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include #include #include #include #include #include "define.h" #include "layout.h" #include "view.h" #include "data/datamgr.h" #include "grid/grid.h" #include "util/listmgr.h" #include "util/util.h" #define TEXT_NOCONTENT "No Music" #define TEXT_NOW_PLAYING "Now Playing" #define GRID_PADDING 26 #define GRID_ITEM_X (488 + GRID_PADDING) #define GRID_ITEM_Y (134 + GRID_PADDING) #define GRID_NUM_ITEM 4 #define BOX_PADDING (62 - GRID_PADDING) struct _priv { Evas_Object *base; Evas_Object *layout; Evas_Object *menu_btn; Evas_Object *view_btn; layoutmgr *lmgr; struct listmgr *listmgr; struct listmgr_data *ldata; struct datamgr *dmgr[E_DATA_MAX]; Eina_List *media_list; app_media *playing_info; int view_mode; struct grid_data *gdata; }; static bool _update_playing_info(void *data, Evas_Object *base) { Evas_Object *content, *image; app_media_info *info; struct _priv *priv; if (!data || !base) { _ERR("invalid argument"); return false; } priv = data; content = elm_object_part_content_get(base, PART_ITEM_CONTENT); if (!content) { _ERR("failed to get content part"); return false; } image = elm_object_part_content_get(content, PART_PLAYING_CONTENT_THUMBNAIL); if (!image) { _ERR("failed to get image object"); return false; } info = app_media_get_info(priv->playing_info); if (!info) { _ERR("failed to get app media info"); return false; } elm_image_file_set(image, info->thumbnail_path, NULL); elm_image_aspect_fixed_set(image, EINA_FALSE); elm_object_part_text_set(content, PART_PLAYING_CONTENT_TITLE, info->title); elm_object_part_text_set(content, PART_PLAYING_CONTENT_ARTIST, info->audio->artist); elm_object_part_text_set(content, PART_PLAYING_CONTENT_ALBUM, info->audio->album); if (info->favorite) elm_object_signal_emit(content, SIG_PLAYING_SHOW_FAV, SIG_SOURCE_SRC); else elm_object_signal_emit(content, SIG_PLAYING_HIDE_FAV, SIG_SOURCE_SRC); return true; } static bool _draw_playing_title(Evas_Object *base) { Evas_Object *btn; btn = elm_button_add(base); if (!btn) { _ERR("failed to create button object"); return false; } elm_object_style_set(btn, STYLE_BTN_INDEX); elm_object_text_set(btn, TEXT_NOW_PLAYING); elm_object_part_content_set(base, PART_ITEM_TITLE, btn); return true; } static bool _draw_playing_content(Evas_Object *base) { Evas_Object *btn, *image; btn = elm_button_add(base); if (!btn) { _ERR("failed to create button object"); return false; } elm_object_style_set(btn, STYLE_BTN_PLAYING_CONTENT); image = elm_image_add(btn); if (!image) { _ERR("failed to create image object"); return false; } elm_object_part_content_set(btn, PART_PLAYING_CONTENT_THUMBNAIL, image); elm_object_part_content_set(base, PART_ITEM_CONTENT, btn); return true; } static bool _draw_playing_info(void *data, Evas_Object *base) { if (!base) { _ERR("invalid argument"); return false; } if (!_draw_playing_title(base)) { _ERR("failed to draw playing title"); return false; } if (!_draw_playing_content(base)) { _ERR("failed to draw playing content"); return false; } return true; } static void _recent_item_selected(struct _priv *priv, app_media *am) { app_media_info *info; struct view_update_data vdata; struct datamgr *dmgr; info = app_media_get_info(am); if (!info) { _ERR("failed to get app media info"); return; } dmgr = priv->dmgr[E_DATA_MEDIA]; if (!dmgr) return; vdata.list = dmgr->ops->get_list(dmgr->handle, E_LIST_MEDIA, NULL); vdata.index = util_get_media_index_from_id(vdata.list, info->media_id); viewmgr_update_view(VIEW_MPLAYER, UPDATE_CONTENT, &vdata); viewmgr_push_view(VIEW_MPLAYER); } static void _playing_selected_cb(void *data, Evas_Object *obj) { struct view_update_data vdata; struct datamgr *dmgr; struct _priv *priv; if (!data || !obj) return; priv = data; dmgr = priv->dmgr[E_DATA_MEDIA]; if (!dmgr) return; vdata.list = dmgr->ops->get_list(dmgr->handle, E_LIST_MEDIA, NULL); vdata.index = util_get_media_index(vdata.list, priv->playing_info); viewmgr_update_view(VIEW_MPLAYER, UPDATE_CONTENT, &vdata); viewmgr_push_view(VIEW_MPLAYER); } static struct listmgr_data *_create_listmgr_data(struct _priv *priv) { struct listmgr_data *data; struct play_info_data *pdata; data = calloc(1, sizeof(*data)); if (!data) goto err; data->menu_btn = priv->menu_btn; data->view_btn = priv->view_btn; pdata = calloc(1, sizeof(*pdata)); if (!pdata) goto err2; pdata->draw = _draw_playing_info; pdata->update = _update_playing_info; pdata->selected_cb = _playing_selected_cb; pdata->cb_data = priv; data->pdata = pdata; return data; err2: free(data); err: _ERR("failed to allocate memory"); return NULL; } static struct datamgr *_get_datamgr(struct _priv *priv) { struct datamgr *dmgr; switch (priv->view_mode) { case E_MUSIC_SONG: case E_MUSIC_GENRE: dmgr = priv->dmgr[E_DATA_MEDIA]; break; case E_MUSIC_ALBUM: case E_MUSIC_ARTIST: dmgr = priv->dmgr[E_DATA_ALBUM]; break; default: dmgr = NULL; break; } return dmgr; } static void _update_content_info(struct _priv *priv) { struct datamgr *dmgr; int count; char buf[128]; dmgr = _get_datamgr(priv); if (!dmgr) return; count = dmgr->ops->get_count(dmgr->handle, E_FILE_MUSIC); if (count < 0) { _ERR("failed to get media count"); return; } snprintf(buf, sizeof(buf), "%d Songs", count); elm_object_part_text_set(priv->base, PART_BASE_CONTENT_INFO, buf); } static void _clear_content_list(struct _priv *priv) { struct datamgr *dmgr; if (priv->media_list) { dmgr = _get_datamgr(priv); if (!dmgr) return; priv->gdata->free_item_list(dmgr, priv->media_list); priv->media_list = NULL; } listmgr_clear_content_list(priv->listmgr); } static void _update_content_list(struct _priv *priv) { Eina_List *list; struct datamgr *dmgr; if (priv->media_list) { _update_content_info(priv); return; } priv->gdata = get_music_grid_data(priv->view_mode); dmgr = _get_datamgr(priv); if (!dmgr) return; list = priv->gdata->get_item_list(dmgr); if (!list) { elm_object_part_text_set(priv->layout, PART_NOCONTENT, TEXT_NOCONTENT); return; } priv->gdata->data = dmgr; if (!listmgr_update_content_list(priv->listmgr, list, priv->gdata)) _ERR("failed to update list area"); priv->media_list = list; _update_content_info(priv); } static app_media *_get_playing_item(Eina_List *list) { GList *rlist; app_media *am; struct recent_data *rdata; int r; rlist = NULL; am = NULL; r = app_contents_get_recent_list(CONTENTS_MUSIC, 1, &rlist); if (r != APP_CONTENTS_ERROR_NONE) { _ERR("failed to get movie recent list"); return NULL; } rdata = g_list_nth_data(rlist, 0); if (rdata && rdata->id) am = util_find_media_info(list, rdata->id); app_contents_free_recent_list(rlist); return am; } static void _update_playing_item(struct _priv *priv, const char *id) { Eina_List *list; app_media *am; app_media_info *info; struct datamgr *dmgr; dmgr = priv->dmgr[E_DATA_MEDIA]; if (!dmgr) return; list = dmgr->ops->get_list(dmgr->handle, E_LIST_MEDIA, NULL); if (id) am = util_find_media_info(list, id); else am = _get_playing_item(list); if (!am) { _ERR("failed to get app media"); return; } info = app_media_get_info(am); if (!info) { _ERR("failed to get app media info"); return; } priv->playing_info = am; if (!listmgr_update_play_info(priv->listmgr, info)) _ERR("failed to update now playing item"); } static void _destroy_datamgr(struct _priv *priv) { int i; for (i = 0; i < E_DATA_MAX; i++) datamgr_destroy(priv->dmgr[i]); } static void _destroy_utils(struct _priv *priv) { _destroy_datamgr(priv); listmgr_destroy(priv->listmgr); free(priv->ldata->pdata); free(priv->ldata); } static bool _create_utils(struct _priv *priv) { struct listmgr *listmgr; struct listmgr_data *ldata; struct datamgr *dmgr; int i; for (i = 0; i < E_DATA_MAX; i++) { dmgr = datamgr_create(i, MUSIC_MEDIA_COND, E_SOURCE_ALL); if (!dmgr) { _ERR("failed to create datamgr"); _destroy_datamgr(priv); return false; } priv->dmgr[i] = dmgr; } ldata = _create_listmgr_data(priv); if (!ldata) { _ERR("failed to create listmgr data"); _destroy_datamgr(priv); return false; } listmgr = listmgr_create(priv->layout, (void *)ldata); if (!listmgr) { _ERR("failed to create listmgr"); _destroy_datamgr(priv); free(ldata); return false; } priv->ldata = ldata; priv->listmgr = listmgr; return true; } static bool _create(layoutmgr *lmgr, void *data) { struct layout_data *ld; struct _priv *priv; Evas_Object *base, *layout; if (!lmgr) { _ERR("failed to get layoutmgr"); return false; } if (!data) { _ERR("invalid argument"); return false; } ld = data; priv = calloc(1, sizeof(*priv)); if (!priv) { _ERR("failed to allocate priv"); return false; } base = layoutmgr_get_base(lmgr); if (!base) { _ERR("failed to get base object"); goto err; } layout = elm_layout_add(base); if (!layout) { _ERR("failed to create layout"); goto err; } if (!elm_layout_file_set(layout, EDJEFILE, GRP_MUSIC_LAYOUT)) { _ERR("failed to set layout file"); goto err2; } priv->base = base; priv->layout = layout; priv->menu_btn = ld->top; priv->view_btn = ld->bottom; priv->lmgr = lmgr; priv->gdata = get_music_grid_data(E_MUSIC_SONG); if (!_create_utils(priv)) { _ERR("failed to create utils"); goto err2; } layoutmgr_set_layout_data(lmgr, LAYOUT_MUSIC, priv); if (!listmgr_draw_list_area(priv->listmgr)) { _ERR("failed to draw list area"); goto err3; } return true; err3: _destroy_utils(priv); err2: evas_object_del(layout); err: free(priv); return false; } static void _destroy(void *layout_data) { struct _priv *priv; struct datamgr *dmgr; if (!layout_data) { _ERR("failed to get layout data"); return; } priv = layout_data; dmgr = _get_datamgr(priv); priv->gdata->free_item_list(dmgr, priv->media_list); _destroy_utils(priv); evas_object_del(priv->layout); free(priv); } static void _show(void *layout_data) { struct _priv *priv; if (!layout_data) { _ERR("failed to layout data"); return; } priv = layout_data; evas_object_show(priv->layout); elm_object_part_content_set(priv->base, PART_BASE_THUMBNAIL_AREA, priv->layout); } static void _hide(void *layout_data) { struct _priv *priv; if (!layout_data) { _ERR("failed to get layout data"); return; } priv = layout_data; evas_object_hide(priv->layout); elm_object_part_content_unset(priv->base, PART_BASE_THUMBNAIL_AREA); } static void _update(void *layout_data, int update_type, void *data) { struct view_update_data *vdata; struct _priv *priv; int mode; if (!layout_data) { _ERR("failed to get layout data"); return; } priv = layout_data; switch (update_type) { case UPDATE_CONTENT: _update_content_list(priv); _update_playing_item(priv, NULL); break; case UPDATE_CONTENT_ITEM: listmgr_update_content_item(priv->listmgr); _update_playing_item(priv, NULL); break; case UPDATE_PLAY_INFO: if (!data) { _ERR("invalid argument"); return; } vdata = data; _update_playing_item(priv, vdata->id); break; case UPDATE_FOCUS: listmgr_focus_play_info(priv->listmgr); break; case UPDATE_BACK: listmgr_focus_content_list(priv->listmgr, NULL); break; case UPDATE_RECENT: if (!data) { _ERR("invalid argument"); return; } _update_content_list(priv); _recent_item_selected(priv, data); break; case UPDATE_FOCUS_STATE: listmgr_set_focus_state(priv->listmgr, EINA_FALSE); break; case UPDATE_VIEW_MODE: if (!data) { _ERR("invalid argument"); return; } vdata = data; mode = vdata->index; /* Folder view mode will be implemented later. */ if (mode == E_MUSIC_FOLDER) return; if (mode == priv->view_mode) return; _clear_content_list(priv); priv->view_mode = mode; _update_content_list(priv); break; default: break; } } static layout_class _lclass = { .layout_id = LAYOUT_MUSIC, .create = _create, .show = _show, .hide = _hide, .destroy = _destroy, .update = _update, }; layout_class *layout_music_get_lclass(void) { return &_lclass; }