2 * Copyright (c) 2015 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>
18 #include <app_debug.h>
19 #include <app_contents.h>
25 #include "util/util.h"
27 #define TEXT_LIVETV "Live TV"
28 #define TEXT_FAVORITE "Favorite"
30 #define VIDEO_COPYRIGHT "Unknown"
32 #define NUM_MENU_BTN 4
35 #define TABLE_PADDING_X 0
36 #define TABLE_PADDING_Y 0
39 ACTION_LIVETV_BTN = 0,
56 Evas_Object *menu_btn[NUM_MENU_BTN];
59 Eina_List *favorite_list;
68 struct _content_info {
73 int app_contents_type;
76 static struct _menu_info menu_info[] = {
79 .style = STYLE_BTN_FAVORITE,
80 .disabled = EINA_FALSE
84 .style = STYLE_BTN_DELETE,
89 .style = STYLE_BTN_EMPTY,
94 .style = STYLE_BTN_EMPTY,
99 struct _content_info content_info[] = {
101 .grid_x = GRID_ITEM_X_MOVIE,
102 .grid_y = GRID_ITEM_Y_MOVIE,
103 .style = STYLE_GRID_MOVIE_ITEM_FAVORITE,
104 .app_contents_type = CONTENTS_MOVIE
107 .grid_x = GRID_ITEM_X_GALLERY,
108 .grid_y = GRID_ITEM_Y_GALLERY,
109 .style = STYLE_GRID_GALLERY_ITEM_FAVORITE,
110 .app_contents_type = CONTENTS_GALLERY
113 .grid_x = GRID_ITEM_X_MUSIC,
114 .grid_y = GRID_ITEM_Y_MUSIC,
115 .style = STYLE_GRID_SONG_ITEM_FAVORITE,
116 .app_contents_type = CONTENTS_MUSIC
120 static void _key_down_cb(int id, void *data, Evas *e, Evas_Object *obj,
121 Evas_Event_Key_Down *ev)
126 if (!strcmp(ev->keyname, KEY_BACK) ||
127 !strcmp(ev->keyname, KEY_BACK_REMOTE))
128 viewmgr_hide_view(VIEW_ACTION_MENU);
131 static void _mouse_move_cb(int id, void *data, Evas *e, Evas_Object *obj,
132 Evas_Event_Mouse_Move *ev)
140 case ACTION_LIVETV_BTN:
141 case ACTION_MENU_BTN:
142 if (!elm_object_focus_get(obj))
143 elm_object_focus_set(obj, EINA_TRUE);
146 case ACTION_FAVORITE_GRID:
147 it = elm_gengrid_at_xy_item_get(obj, ev->cur.canvas.x,
148 ev->cur.canvas.y, NULL, NULL);
153 if (!elm_object_item_focus_get(it))
154 elm_object_item_focus_set(it, EINA_TRUE);
160 static input_handler _handler = {
161 .key_down = _key_down_cb,
162 .mouse_move = _mouse_move_cb
165 static char *_grid_text_get(void *data, Evas_Object *obj, const char *part)
168 app_media_info *info;
176 info = app_media_get_info(am);
178 _ERR("failed to get media info");
182 if (!strcmp(part, PART_ELM_TEXT_TITLE))
183 return strdup(info->title);
184 else if (!strcmp(part, PART_ELM_TEXT_ARTIST))
185 return strdup(info->audio->artist);
186 else if (!strcmp(part, PART_ELM_TEXT_ALBUM))
187 return strdup(info->audio->album);
188 else if (!strcmp(part, PART_ELM_TEXT_PLAYTIME)) {
189 if (info->media_type != MEDIA_CONTENT_TYPE_VIDEO)
192 util_time_string(buf, sizeof(buf),
193 info->video->duration, false);
200 static Evas_Object *_grid_content_get(void *data,
201 Evas_Object *obj, const char *part)
203 Evas_Object *content;
205 app_media_info *info;
206 struct color_data bg;
213 info = app_media_get_info(am);
215 _ERR("failed to get media info");
220 if (!strcmp(part, PART_ELM_SWALLOW_THUMBNAIL)) {
221 content = util_add_image(obj, info->thumbnail_path);
225 evas_object_show(content);
226 } else if (!strcmp(part, PART_ELM_SWALLOW_VIDEO)) {
227 if (info->media_type != MEDIA_CONTENT_TYPE_VIDEO)
230 content = util_add_image(obj, IMAGE_THUMBNAIL_PLAY);
234 evas_object_show(content);
235 } else if (!strcmp(part, PART_ELM_SWALLOW_TEXTBG)) {
236 content = evas_object_rectangle_add(obj);
240 app_contents_get_color(info->title, NULL, &bg);
241 evas_object_color_set(content, bg.r, bg.g, bg.b, bg.a);
243 evas_object_show(content);
249 _ERR("failed to create evas object");
253 Elm_Gengrid_Item_Class *_get_grid_item_class(int type)
255 Elm_Gengrid_Item_Class *ic;
257 ic = elm_gengrid_item_class_new();
259 _ERR("failed to create gengrid item class");
263 ic->func.text_get = _grid_text_get;
264 ic->func.content_get = _grid_content_get;
265 ic->item_style = content_info[type].style;
270 static bool _check_movie_type(app_media_info *info)
272 return strcmp(info->video->copyright, VIDEO_COPYRIGHT);
275 static int _get_content_type(app_media_info *info)
279 type = E_CONTENT_MAX;
280 switch (info->media_type) {
281 case MEDIA_CONTENT_TYPE_IMAGE:
282 type = E_CONTENT_GALLERY;
284 case MEDIA_CONTENT_TYPE_VIDEO:
285 if (_check_movie_type(info))
286 type = E_CONTENT_MOVIE;
288 type = E_CONTENT_GALLERY;
290 case MEDIA_CONTENT_TYPE_MUSIC:
291 type = E_CONTENT_MUSIC;
300 static void _free_favorite_list(Eina_List *list)
304 EINA_LIST_FREE(list, am)
305 app_media_destroy(am);
308 static void _favorite_list_foreach(gpointer data, gpointer user_data)
316 if (!data || !user_data) {
317 _ERR("invalid argument");
322 l = (Eina_List **)user_data;
324 r = media_info_get_media_from_db(id, &media);
325 if (r != MEDIA_CONTENT_ERROR_NONE) {
326 _ERR("failed to get media handle");
330 am = app_media_create(media);
332 _ERR("failed to create app media");
333 media_info_destroy(media);
337 *l = eina_list_append(*l, am);
340 static Eina_List *_get_favorite_list(int type)
346 r = media_content_connect();
347 if (r != MEDIA_CONTENT_ERROR_NONE) {
348 _ERR("failed to connect to media content");
353 if (app_contents_get_favorite_list(type, &id_list)
354 != APP_CONTENTS_ERROR_NONE) {
355 _ERR("failed to get favorite list");
360 g_list_foreach(id_list, _favorite_list_foreach, &list);
362 app_contents_free_favorite_list(id_list);
364 media_content_disconnect();
369 static bool _draw_livetv_btn(struct _priv *priv)
373 btn = elm_button_add(priv->base);
375 _ERR("failed to create button object");
379 elm_object_style_set(btn, STYLE_BTN_LIVETV);
380 elm_object_text_set(btn, TEXT_LIVETV);
382 inputmgr_add_callback(btn, ACTION_LIVETV_BTN, &_handler, priv);
384 elm_object_part_content_set(priv->base, PART_ACTION_TV_BTN, btn);
386 evas_object_show(btn);
388 elm_object_focus_next_object_set(btn, btn, ELM_FOCUS_LEFT);
389 elm_object_focus_next_object_set(btn, btn, ELM_FOCUS_RIGHT);
396 static bool _draw_menu_area(struct _priv *priv)
398 Evas_Object *table, *btn;
402 table = util_add_table(priv->base, TABLE_PADDING_X, TABLE_PADDING_Y);
404 _ERR("failed to add table");
408 for (i = 0; i < NUM_MENU_BTN; i++) {
409 btn = elm_button_add(priv->base);
411 _ERR("failed to create button object");
412 evas_object_del(table);
416 elm_object_style_set(btn, menu_info[i].style);
417 elm_object_text_set(btn, menu_info[i].title);
419 if (menu_info[i].disabled)
420 elm_object_disabled_set(btn, EINA_TRUE);
422 evas_object_show(btn);
424 inputmgr_add_callback(btn, ACTION_MENU_BTN, &_handler, priv);
426 elm_object_focus_next_object_set(btn, priv->grid,
429 col = i % MAX_BTN_COL;
430 row = i / MAX_BTN_COL;
432 elm_table_pack(table, btn, col, row, 1, 1);
434 priv->menu_btn[i] = btn;
437 evas_object_show(table);
439 elm_object_focus_next_object_set(priv->menu_btn[0], priv->menu_btn[0],
441 elm_object_focus_next_object_set(priv->menu_btn[NUM_MENU_BTN - 1],
442 priv->menu_btn[NUM_MENU_BTN - 1],
445 elm_object_part_content_set(priv->base, PART_ACTION_MENU_AREA, table);
450 static bool _draw_favorite_area(struct _priv *priv)
454 elm_object_part_text_set(priv->base, PART_ACTION_FAVORITE_TITLE,
457 grid = util_add_gengrid(priv->base, 0, 0, EINA_FALSE);
459 _ERR("failed to create gengrid object");
463 inputmgr_add_callback(grid, ACTION_FAVORITE_GRID, &_handler, priv);
465 elm_object_focus_next_object_set(grid, grid, ELM_FOCUS_LEFT);
466 elm_object_focus_next_object_set(grid, grid, ELM_FOCUS_RIGHT);
468 elm_object_part_content_set(priv->base,
469 PART_ACTION_FAVORITE_AREA, grid);
476 static void _update_favorite_area(struct _priv *priv, int type)
479 Elm_Gengrid_Item_Class *ic;
481 Eina_List *favorite_l, *l;
484 elm_gengrid_clear(priv->grid);
486 elm_gengrid_item_size_set(priv->grid,
487 elm_config_scale_get() * content_info[type].grid_x,
488 elm_config_scale_get() * content_info[type].grid_y);
490 ic = _get_grid_item_class(type);
492 favorite_l = _get_favorite_list(content_info[type].app_contents_type);
494 EINA_LIST_FOREACH(favorite_l, l, am) {
495 it = elm_gengrid_item_append(priv->grid, ic, am, NULL, NULL);
497 elm_object_item_data_set(it, am);
500 elm_gengrid_item_class_free(ic);
502 priv->favorite_list = favorite_l;
505 static bool _draw_items(struct _priv *priv)
507 if (!_draw_livetv_btn(priv)) {
508 _ERR("failed to draw livetv button");
512 if (!_draw_favorite_area(priv)) {
513 _ERR("failed to draw favorite area");
517 if (!_draw_menu_area(priv)) {
518 _ERR("failed to draw menu button");
525 static bool _update_items(struct _priv *priv, struct view_update_data *vdata)
531 am = eina_list_nth(vdata->list, vdata->index);
533 _ERR("failed to get app media");
537 mi = app_media_get_info(am);
539 _ERR("failed to get app media info");
543 type = _get_content_type(mi);
545 _update_favorite_area(priv, type);
550 static Evas_Object *_create(Evas_Object *win, void *data)
556 _ERR("failed to get win object");
560 priv = calloc(1, sizeof(*priv));
562 _ERR("failed to allocate priv");
566 base = elm_layout_add(win);
568 _ERR("failed to create base object");
573 elm_layout_file_set(base, EDJEFILE, GRP_ACTION_MENU_VIEW);
575 evas_object_size_hint_weight_set(base, EVAS_HINT_EXPAND,
577 elm_win_resize_object_add(win, base);
582 viewmgr_set_view_data(VIEW_ACTION_MENU, priv);
584 if (!_draw_items(priv)) {
585 _ERR("failed to draw items");
593 static void _show(void *view_data)
598 _ERR("failed to get view data");
604 evas_object_show(priv->base);
606 elm_object_focus_set(priv->tv_btn, EINA_TRUE);
609 static void _hide(void *view_data)
614 _ERR("failed to get view data");
620 evas_object_hide(priv->base);
623 static void _update(void *view_data, int update_type, void *data)
628 _ERR("failed to get view data");
633 _ERR("invalid argument");
639 switch (update_type) {
641 _update_items(priv, data);
648 static void _destroy(void *view_data)
654 _ERR("failed to get view data");
660 inputmgr_remove_callback(priv->tv_btn, &_handler);
661 inputmgr_remove_callback(priv->grid, &_handler);
663 for (i = 0; i < NUM_MENU_BTN; i++)
664 inputmgr_remove_callback(priv->menu_btn[i], &_handler);
666 if (priv->favorite_list)
667 _free_favorite_list(priv->favorite_list);
669 evas_object_del(priv->base);
674 static view_class _vclass = {
675 .view_id = VIEW_ACTION_MENU,
683 view_class *view_action_menu_get_vclass(void)