2 * Copyright 2012 Samsung Electronics Co., Ltd
4 * Licensed under the Flora License, Version 1.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.tizenopensource.org/license
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.
18 #include "gl-gridview.h"
19 #include "gl-ui-util.h"
22 #include "gl-albums.h"
24 #include "gl-ext-ug-load.h"
25 #include "gl-ext-exec.h"
26 #include "gl-controlbar.h"
27 #include "gl-nocontents.h"
28 #include "gl-notify.h"
29 #include "gl-strings.h"
35 /* Icon swallowed to part "elm.swallow.icon" */
36 #define GL_GRID_TOUCH_RANGE 20
39 _gl_grid_sel_icon(void *data)
42 gl_grid_sel_cb(data, NULL, NULL);
46 _gl_grid_item_check_changed(void *data, Evas_Object *obj, void *event_info)
50 gl_item *gitem = (gl_item *) data;
52 gl_appdata *ad = (gl_appdata *)gitem->ad;
53 int view_mode = gl_get_view_mode(ad);
54 Evas_Object *view_ly = NULL;
55 Elm_Object_Item *nf_it = NULL;
58 if (view_mode == GL_VIEW_THUMBS_EDIT) {
59 view_ly = ad->gridinfo.edit_layout;
60 nf_it = ad->gridinfo.nf_it_edit;
66 Eina_Bool checked = elm_check_state_get(obj);
67 gitem->checked = checked;
70 gl_dbg("Append:%s", gitem->item->file_url);
71 _gl_data_selected_list_append(ad, gitem);
75 gl_dbg("Remove:%s", gitem->item->file_url);
76 _gl_data_selected_list_remove(ad, gitem);
79 /* Display selectioninfo */
80 int cnt = _gl_data_selected_list_count(ad);
81 _gl_notify_create_selinfo(ad, view_ly, nf_it, ad->gridinfo.thumbs_cnt,
86 _gl_grid_shrink_resp_cb(void *data, Evas_Object *obj,
87 const char *emission, const char *source)
92 _gl_grid_sel_icon(data);
94 edje_object_signal_callback_del(obj,
95 "shrink,expand,done", "bg", _gl_grid_shrink_resp_cb);
99 static Evas_Object *__gl_grid_get_content(void *data, Evas_Object *obj, const char *part)
102 GL_CHECK_NULL(strlen(part));
104 gl_item *gitem = (gl_item *) data;
105 GL_CHECK_NULL(gitem->item);
106 GL_CHECK_NULL(gitem->ad);
107 gl_appdata *ad = (gl_appdata *)gitem->ad;
108 int view_mode = gl_get_view_mode(ad);
109 int item_size = ad->gridinfo.icon_size;
110 bool is_expired_drm = false;
112 if (!g_strcmp0(part, GL_THUMB_ICON)) {
113 Evas_Object *layout = NULL;
115 char *drm_path = NULL;
116 unsigned int orient = 0;
118 /* Is it DRM file? Has a valid RO? */
119 if(gl_drm_is_drm_file(gitem->item->file_url) &&
120 gl_drm_check_valid_ro(gitem->item->file_url,
121 gl_drm_get_permtype(gitem->item->type)) == false) {
122 path = GL_DEFAULT_THUMB_ICON;
123 is_expired_drm = true;
124 } else if (ad->maininfo.medias_cnt < 2 &&
125 gitem->item->type == MEDIA_CONTENT_TYPE_IMAGE) {
126 if (!g_strcmp0(GL_DB_DEFAULT_THUMB, gitem->item->thumb_url)) {
127 path = GL_DEFAULT_THUMB_ICON;
129 char *drm_path = gl_drm_get_file_path(gitem);
130 path = _GETICON(drm_path);
131 if (gl_is_image_valid(ad, path) == false)
132 path = _GETICON(gitem->item->thumb_url);
133 #ifdef _USE_ROTATE_BG
134 /* Rotate bg if it's created from original file */
135 if (!g_strcmp0(path, gitem->item->file_url))
136 _gl_exif_get_orientation(path, &orient);
141 ret = _gl_get_thumb(ad, gitem->item->file_url,
142 &gitem->item->thumb_url);
143 /* Use default image */
145 path = GL_DEFAULT_THUMB_ICON;
147 path = gitem->item->thumb_url;
150 if (gitem->item->type == MEDIA_CONTENT_TYPE_VIDEO) {
151 unsigned int v_dur = 0;
152 if (gitem->item->video_info) {
153 v_dur = gitem->item->video_info->duration;
156 if (gitem->item->video_info == NULL)
159 bk_len = gitem->item->video_info->bookmarks;
160 layout = _gl_thumb_show_part_icon_video(obj, path,
165 layout = _gl_thumb_show_part_icon_image(obj, path,
176 evas_object_event_callback_add(layout,
177 EVAS_CALLBACK_MOUSE_DOWN, gl_grid_item_mouse_down, gitem);
178 evas_object_event_callback_add(layout,
179 EVAS_CALLBACK_MOUSE_UP, gl_grid_item_mouse_up, gitem);
183 } else if (!g_strcmp0(part, GL_THUMB_CHECKBOX) &&
184 view_mode == GL_VIEW_THUMBS_EDIT) {
185 Evas_Object *ck = NULL;
186 ck = _gl_thumb_show_part_checkbox(obj, gitem->checked,
187 _gl_grid_item_check_changed,
191 gitem->check_obj = ck;
199 _gl_grid_create_items(void *data, Evas_Object *parent)
201 GL_CHECK_FALSE(data);
202 gl_appdata *ad = (gl_appdata *)data;
205 gl_item *gitem = NULL;
207 /* Get all medias count of current album */
208 int cnt = ad->maininfo.medias_cnt;
209 gl_dbg("List count : %d gv_mode : %d", cnt, ad->gridinfo.grid_view_mode);
211 ad->gridinfo.thumbgic.item_style = GL_GENGRID_ITEM_STYLE_THUMBNAIL;
212 ad->gridinfo.thumbgic.func.text_get = NULL;
213 ad->gridinfo.thumbgic.func.content_get = __gl_grid_get_content;
215 elm_gengrid_clear(parent);
216 for (i = 1; i <= cnt; i++)
218 _gl_data_get_item_by_index(ad, i, false, &gitem);
219 if (gitem == NULL || gitem->item == NULL ||
220 gitem->item->uuid == NULL) {
221 gl_dbgE("Invalid gitem. continue...");
225 if (!gitem->item->file_url)
227 gl_dbg("file_url is invalid.");
228 ret = _gl_data_delete_media(ad, gitem->item);
233 _gl_data_selected_list_remove(ad, gitem);
234 _gl_data_item_list_remove(ad, gitem);
241 if (ad->gridinfo.back_to_normal)
243 gitem->checked = false;
244 //gitem->check_obj = NULL;
247 if (ad->gridinfo.grid_view_mode == GL_GRID_IMAGES &&
248 gitem->item->type != MEDIA_CONTENT_TYPE_IMAGE)
251 gitem->elm_item = elm_gengrid_item_append(parent,
252 &(ad->gridinfo.thumbgic),
257 gitem->sequence = item_cnt;
261 /* Disable grid item selection callback */
262 elm_gengrid_select_mode_set(parent, ELM_OBJECT_SELECT_MODE_NONE);
264 ad->gridinfo.thumbs_cnt = item_cnt;
265 ad->gridinfo.back_to_normal = false;
278 gl_grid_item_mouse_down(void *data, Evas *e,
279 Evas_Object *obj, void *event_info)
282 GL_CHECK(event_info);
284 gl_item *gitem = (gl_item *) data;
286 gl_appdata *ad = (gl_appdata *)gitem->ad;
287 Evas_Event_Mouse_Down *ev = (Evas_Event_Mouse_Down *) event_info;
289 ad->gridinfo.grid_touch_info.x = ev->output.x;
290 ad->gridinfo.grid_touch_info.y = ev->output.y;
292 if (ad->uginfo.ug_called_by_me == NULL)
294 edje_object_signal_emit(_EDJ(obj), "mouse,down,shrink", "bg");
295 ad->gridinfo.grid_touch_info.b_pressed = true;
300 gl_grid_item_mouse_up(void *data, Evas *e,
301 Evas_Object *obj, void *event_info)
304 gl_item *gitem = (gl_item *) data;
306 gl_appdata *ad = (gl_appdata *)gitem->ad;
308 if (!event_info || !obj)
313 Evas_Event_Mouse_Up *ev = event_info;
314 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD ||
315 ev->event_flags & EVAS_EVENT_FLAG_ON_SCROLL)
319 if ((abs(ad->gridinfo.grid_touch_info.x - ev->output.x) > GL_GRID_TOUCH_RANGE) ||
320 (abs(ad->gridinfo.grid_touch_info.y - ev->output.y) > GL_GRID_TOUCH_RANGE))
327 if (ad->gridinfo.grid_touch_info.b_pressed)
329 edje_object_signal_emit(_EDJ(obj), "mouse,up,expand", "bg");
330 edje_object_signal_callback_add(_EDJ(obj),
331 "shrink,expand,done", "bg", _gl_grid_shrink_resp_cb, data);
332 ad->gridinfo.grid_touch_info.b_pressed = false;
337 if (ad->gridinfo.grid_touch_info.b_pressed)
339 edje_object_signal_emit(_EDJ(obj), "mouse,up,expand", "bg");
340 ad->gridinfo.grid_touch_info.b_pressed = false;
345 * Set new view to all/image_grid_view.
347 * b_noc, true: it's nocontents view, false: normal view.
349 static int _gl_grid_set_view(void *data, Evas_Object *view, bool b_noc)
351 GL_CHECK_VAL(data, -1);
352 gl_appdata *ad = (gl_appdata *)data;
353 gl_grid_mode view_mode = ad->gridinfo.grid_view_mode;
357 ad->gridinfo.all_view = view;
359 gl_grid_set_nocontents(ad, view);
361 gl_grid_set_nocontents(ad, NULL);
364 ad->gridinfo.images_view = view;
366 gl_grid_set_nocontents(ad, view);
368 gl_grid_set_nocontents(ad, NULL);
378 gl_grid_sel_cb(void *data, Evas_Object *obj, void *event_info)
381 gl_item *gitem = (gl_item *) data;
382 GL_CHECK(gitem->item);
383 GL_CHECK(gitem->item->file_url);
384 GL_CHECK(strlen(gitem->item->file_url));
386 gl_appdata *ad = (gl_appdata *)gitem->ad;
387 int view_mode = gl_get_view_mode(ad);
390 if (view_mode != GL_VIEW_THUMBS)
392 //gl_dbg("EditMode.. now return.");
400 if (gitem->item->type == MEDIA_CONTENT_TYPE_IMAGE ||
401 gitem->item->type == MEDIA_CONTENT_TYPE_VIDEO)
403 gl_dbg("Loading UG-IMAGE(VIDEO)-VIEWER");
404 gl_ext_load_iv_ug(ad, gitem, GL_UG_IV);
409 * When select album, show first (GL_FIRST_VIEW_END_POS+1) medias.
410 * Then use idler to get other medias from DB and appened
412 * In order to reduce transit time of first show of thumbnails view.
413 * Cause most of time is spent for getting records from DB,
414 * so we get first (GL_FIRST_VIEW_END_POS+1) items and show thumbnails view,
415 * it will accelerate view show.
418 gl_grid_idler_append_items(void *data)
420 GL_CHECK_VAL(data, -1);
421 gl_appdata *ad = (gl_appdata *)data;
422 GL_CHECK_VAL(ad->albuminfo.current_album, -1);
423 GL_CHECK_VAL(ad->gridinfo.all_view, -1);
426 gl_item *gitem = NULL;
427 /* Get all medias count of current album */
428 int cnt = ad->maininfo.medias_cnt;
431 gl_dbg("First view medias count: %d; girdview mode: %d",
432 cnt, ad->gridinfo.grid_view_mode);
433 if (ad->maininfo.medias_cnt != (GL_FIRST_VIEW_END_POS + 1))
435 gl_dbg("No any more items, return!");
438 /* Get other items from DB */
439 ret = _gl_data_get_item_list(ad, ad->albuminfo.current_album,
440 (GL_FIRST_VIEW_END_POS + 1),
441 GL_GET_UNTIL_LAST_RECORD);
443 gl_dbgE("Get items list failed[%d]!", ret);
447 cnt = ad->maininfo.medias_cnt;
448 gl_dbg("Grid view all medias count: %d", cnt);
450 if (ad->gridinfo.grid_view_mode != GL_GRID_ALL)
452 /* Event gridview mode is wrong, we still need to get other records */
453 gl_dbg("Gridview mode is wrong, return!");
457 /* From (GL_FIRST_VIEW_END_POS + 2)th item to last one */
458 i = GL_FIRST_VIEW_END_POS + 2;
460 for (; i <= cnt; i++)
462 _gl_data_get_item_by_index(ad, i, false, &gitem);
463 if (gitem == NULL || gitem->item == NULL ||
464 gitem->item->uuid == NULL ) {
465 gl_dbgE("Invalid gitem, continue...");
469 if (!gitem->item->file_url)
471 gl_dbg("file_url is invalid.");
472 _gl_data_delete_media(ad, gitem->item);
473 _gl_data_selected_list_remove(ad, gitem);
474 _gl_data_item_list_remove(ad, gitem);
481 if (ad->gridinfo.grid_view_mode == GL_GRID_IMAGES &&
482 gitem->item->type != MEDIA_CONTENT_TYPE_IMAGE)
485 gitem->elm_item = elm_gengrid_item_append(ad->gridinfo.all_view,
486 &(ad->gridinfo.thumbgic),
491 gitem->sequence = item_cnt + GL_FIRST_VIEW_END_POS + 1;
494 gl_dbgW("\tUse idler to append other medias--Done!");
501 ad->gridinfo.thumbs_cnt = item_cnt + GL_FIRST_VIEW_END_POS + 1;
502 gl_dbg("All count appended: %d", ad->gridinfo.thumbs_cnt);
507 static Eina_Bool __gl_grid_append_items_idler_cb(void *data)
509 GL_CHECK_CANCEL(data);
511 /* Try to get other medias from DB and append them to gridview */
512 int ret = gl_grid_idler_append_items(data);
514 gl_dbgE("Failed to append grid items!");
516 gl_dbg("Successful to append grid items!");
519 /* Remove idler after all items appended */
520 _gl_grid_del_append_idler(data);
522 return ECORE_CALLBACK_CANCEL;
526 gl_grid_create_layout(void *data, Evas_Object *parent)
528 GL_CHECK_NULL(parent);
530 gl_appdata *ad = (gl_appdata *)data;
533 Evas_Object *layout = NULL;
534 layout = gl_ui_load_edj(ad->maininfo.naviframe, GL_EDJ_FILE,
536 evas_object_show(layout);
541 Evas_Object *_gl_grid_create_view(void *data, Evas_Object *parent,
542 gl_grid_mode mode, bool b_use_idler)
544 GL_CHECK_NULL(parent);
546 gl_appdata *ad = (gl_appdata *)data;
547 Evas_Object *grid = NULL;
548 ad->gridinfo.grid_view_mode = mode;
549 grid = _gl_thumb_add_gengrid(parent);
551 if (!_gl_grid_create_items(ad, grid)) {
552 evas_object_del(grid);
554 Evas_Object *noc = _gl_nocontents_create(ad);
555 gl_grid_set_nocontents(ad, noc);
556 evas_object_show(noc);
560 gl_dbg("thumbs_cnt : %d", ad->gridinfo.thumbs_cnt);
561 gl_grid_set_item_size(ad, grid);
563 evas_object_show(grid);
566 ad->maininfo.medias_cnt == (GL_FIRST_VIEW_END_POS + 1)) {
567 gl_dbgW("\tUse idler to append other medias--Start");
569 _gl_grid_del_append_idler(ad);
571 ad->gridinfo.grid_append_idler = ecore_idler_add(__gl_grid_append_items_idler_cb,
579 gl_grid_change_to_edit(void *data)
581 GL_CHECK_VAL(data, -1);
582 gl_appdata *ad = (gl_appdata *)data;
583 int view_mode = gl_get_view_mode(ad);
585 Evas_Object *view = NULL;
586 gl_dbg("view_mode: %d", view_mode);
588 if (view_mode == GL_VIEW_THUMBS_EDIT) {
589 view = ad->gridinfo.edit_view;
591 gl_dbgE("Wrong view mode!");
594 GL_CHECK_VAL(view, -1);
596 b_ret = _gl_grid_create_items(ad, view);
597 gl_grid_set_item_size(ad, NULL);
600 gl_dbgE("Create items failed!");
608 gl_grid_change_to_view(void *data)
610 GL_CHECK_VAL(data, -1);
611 gl_appdata *ad = (gl_appdata *)data;
612 int gridview_mode = ad->gridinfo.grid_view_mode;
614 gl_dbg("gridview_mode: %d", gridview_mode);
616 if (ad->gridinfo.all_view == NULL
617 && ad->gridinfo.images_view == NULL)
619 gl_dbg("Error : Any gridview doesn't exist");
623 /* Come back from edit mode, save state */
624 ad->gridinfo.back_to_normal = true;
626 if (gridview_mode == GL_GRID_ALL)
628 b_ret = _gl_grid_create_items(ad, ad->gridinfo.all_view);
630 else if (gridview_mode == GL_GRID_IMAGES)
632 b_ret = _gl_grid_create_items(ad, ad->gridinfo.images_view);
634 gl_grid_set_item_size(ad, NULL);
637 gl_dbgE("Create items failed!");
645 * Get all/image_grid_view.
647 * True returned if it's normal view, if it's nocontents view return false.
649 bool gl_grid_get_view(void *data, Evas_Object **view)
651 GL_CHECK_FALSE(data);
652 gl_appdata *ad = (gl_appdata *)data;
653 gl_grid_mode view_mode = ad->gridinfo.grid_view_mode;
654 Evas_Object *gv = NULL;
659 gv = ad->gridinfo.all_view;
660 if (gv && ad->gridinfo.all_nocontents == NULL)
664 gv = ad->gridinfo.images_view;
665 if (gv && ad->gridinfo.images_nocontents == NULL)
674 gl_dbg("Previous view is Nocontents...");
683 /* Assign new value to all/image_grid_nocontents */
684 int gl_grid_set_nocontents(void *data, Evas_Object *noc)
686 GL_CHECK_VAL(data, -1);
687 gl_appdata *ad = (gl_appdata *)data;
688 gl_grid_mode view_mode = ad->gridinfo.grid_view_mode;
692 ad->gridinfo.all_nocontents = noc;
695 ad->gridinfo.images_nocontents = noc;
704 int gl_grid_set_item_size(void *data, Evas_Object *gridview)
706 GL_CHECK_VAL(data, -1);
707 gl_appdata *ad = (gl_appdata *)data;
709 Evas_Object *gv = NULL;
710 int view_mode = gl_get_view_mode(ad);
716 if (view_mode == GL_VIEW_THUMBS_EDIT) {
718 gv = ad->gridinfo.edit_view;
720 b_view = gl_grid_get_view(ad, &gv);
723 if (!b_view || !gv) {
724 gl_dbgE("gridview is invalid!");
729 if (ad->gridinfo.updated_thumbs_cnt <= 0) {
730 cnt = ad->gridinfo.thumbs_cnt;
732 cnt = ad->gridinfo.updated_thumbs_cnt;
733 ad->gridinfo.updated_thumbs_cnt = 0;
736 return _gl_thumb_set_size(ad, gv, cnt, &(ad->gridinfo.icon_size));
740 gl_grid_update_items(void *data)
742 GL_CHECK_FALSE(data);
743 gl_appdata *ad = (gl_appdata *)data;
744 Eina_Bool res = EINA_FALSE;
745 Evas_Object *gv = NULL;
746 int view_mode = gl_get_view_mode(ad);
750 if (view_mode == GL_VIEW_THUMBS_EDIT)
752 gl_dbg("\n\nEdit_Mode\n");
753 gv = ad->gridinfo.edit_view;
757 b_view = gl_grid_get_view(ad, &gv);
761 res = _gl_grid_create_items(ad, gv);
764 gl_dbg("_gl_grid_create_items() return false...");
765 evas_object_hide(gv);
767 _gl_grid_set_view(ad, NULL, false);
768 Evas_Object *noc = _gl_nocontents_create(ad);
769 evas_object_show(noc);
770 _gl_grid_set_view(ad, noc, true);
772 elm_object_part_content_unset(ad->gridinfo.layout,
774 elm_object_part_content_set(ad->gridinfo.layout,
775 "elm.swallow.view", noc);
779 gl_grid_set_item_size(ad, gv);
784 gl_dbg("Remove nocontents view.");
785 evas_object_hide(gv);
787 _gl_grid_set_view(ad, NULL, false);
789 int view_m = ad->gridinfo.grid_view_mode;
791 Evas_Object *view = NULL;
792 view = _gl_grid_create_view(ad, ad->gridinfo.layout,
794 if ((view_m == GL_GRID_IMAGES &&
795 ad->gridinfo.images_nocontents) ||
796 (view_m == GL_GRID_ALL &&
797 ad->gridinfo.all_nocontents))
800 /* No nocotents removed, gridview created, enable edit button */
802 _gl_ctrl_disable_toolbar_item(ad, false,
808 _gl_grid_set_view(ad, view, b_noc);
810 elm_object_part_content_unset(ad->gridinfo.layout,
812 elm_object_part_content_set(ad->gridinfo.layout,
813 "elm.swallow.view", view);
820 gl_grid_clear_view(void *data)
822 GL_CHECK_VAL(data, -1);
823 gl_appdata *ad = (gl_appdata *)data;
824 ad->gridinfo.segment = NULL;
827 _gl_grid_del_append_idler(data);
829 if (ad->gridinfo.all_view != NULL) {
830 evas_object_del(ad->gridinfo.all_view);
831 ad->gridinfo.all_view = NULL;
834 if (ad->gridinfo.images_view != NULL) {
835 evas_object_del(ad->gridinfo.images_view);
836 ad->gridinfo.images_view = NULL;
838 ad->gridinfo.all_nocontents = NULL;
839 ad->gridinfo.images_nocontents = NULL;
840 ad->gridinfo.edit_it = NULL;
845 /* Update griditem size */
846 int _gl_grid_update_item_size(void *data, Evas_Object *view)
848 GL_CHECK_VAL(data, -1);
849 gl_appdata *ad = (gl_appdata *)data;
850 Evas_Object *_view = NULL;
851 int view_mode = gl_get_view_mode(ad);
854 if (ad->gridinfo.thumbs_cnt <= GL_GRID_ITEM_ZOOM_LEVEL_02_CNT) {
855 gl_dbgW("Thumbs count is less than 7!");
863 if (view_mode == GL_VIEW_THUMBS_EDIT) {
865 _view = ad->gridinfo.edit_view;
867 b_view = gl_grid_get_view(ad, &_view);
870 if (!b_view || !_view) {
871 gl_dbgE("gridview is invalid!");
876 gl_grid_set_item_size(data, _view);
878 _gl_thumb_update_gengrid(_view);
883 int _gl_grid_del_append_idler(void *data)
885 GL_CHECK_VAL(data, -1);
886 gl_appdata *ad = (gl_appdata *)data;
888 if (ad->gridinfo.grid_append_idler) {
889 ecore_idler_del(ad->gridinfo.grid_append_idler);
890 ad->gridinfo.grid_append_idler = NULL;