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 "ge-gridview.h"
19 #include "ge-ui-util.h"
21 #include "ge-ext-ug-load.h"
23 #include "ge-strings.h"
28 /* Icon swallowed to part "elm.swallow.icon" */
29 #define GE_GRID_ICON_SIZE 156
30 #define GE_ITEM_MOUSE_UP_DISTANCE_X 20
31 #define GE_ITEM_MOUSE_UP_DISTANCE_Y 20
32 #define GE_GIRD_ICON_CLICK_TIME_DELAY 0.01f
34 static Elm_Gengrid_Item_Class gic;
35 static int ge_grid_item_cnt = 0;
44 static ge_grid_touch_info ge_touch_info;
46 static void _ge_grid_drag_up(void *data, Evas_Object *obj, void *event_info)
51 static void _ge_grid_drag_right(void *data, Evas_Object *obj, void *event_info)
56 static void _ge_grid_drag_down(void *data, Evas_Object *obj, void *event_info)
61 static void _ge_grid_drag_left(void *data, Evas_Object *obj, void *event_info)
66 static void _ge_grid_drag_stop(void *data, Evas_Object *obj, void *event_info)
71 static void _ge_grid_selected(void *data, Evas_Object *obj, void *event_info)
76 static void _ge_grid_unselected(void *data, Evas_Object *obj, void *event_info)
81 static void _ge_grid_clicked(void *data, Evas_Object *obj, void *event_info)
86 static void _ge_grid_longpress(void *data, Evas_Object *obj, void *event_info)
91 static void _ge_grid_sel(void *data, Evas_Object *obj, void *event_info)
95 if (_ge_get_view_mode() != GE_ThumbnailView_Mode) {
96 //ge_dbgE("EditMode.. now return.");
102 ge_item* gitem = (ge_item*)data;
103 GE_CHECK(gitem->item);
104 GE_CHECK(gitem->ugd);
105 ge_ugdata* ugd = gitem->ugd;
107 if (gitem->item->file_url == NULL || strlen(gitem->item->file_url) <= 0) {
108 ge_dbgE("file_url is invalid!");
111 ge_dbg("file_url: %s.", gitem->item->file_url);
114 if (ugd->file_select_mode == GE_File_Select_Setas) {
115 /* imageviewer only supprot image type while setting wallpaper */
116 if(gitem->item->type == MEDIA_CONTENT_TYPE_IMAGE) {
117 _ge_set_current_item(gitem);
118 ge_dbg("Loading UG-IMAGE(VIDEO)-VIEWER");
119 ge_ext_load_iv_ug(ugd);
120 } else if (gitem->item->type == MEDIA_CONTENT_TYPE_VIDEO &&
121 ugd->popup == NULL) {
122 ge_ui_create_popup(ugd, GE_Popup_OneButton, GE_POPUP_ONLY_SUPPORT_IMAGE);
125 } else if (gitem->item->type == MEDIA_CONTENT_TYPE_IMAGE ||
126 gitem->item->type == MEDIA_CONTENT_TYPE_VIDEO) {
127 _ge_set_current_item(gitem);
128 ge_dbg("Loading UG-IMAGE(VIDEO)-VIEWER");
129 ge_ext_load_iv_ug(ugd);
133 static void _ge_grid_icon_clicked(void *data, Evas_Object *obj, void *event_info)
137 _ge_grid_sel(data, obj, event_info);
140 static void _ge_grid_item_mouse_down(void *data, Evas *e, Evas_Object *obj, void *event_info)
142 Evas_Event_Mouse_Down *ev = (Evas_Event_Mouse_Down*)event_info;
147 ge_item *gitem = (ge_item *)data;
148 GE_CHECK(gitem->ugd);
149 ge_ugdata *ugd = gitem->ugd;
151 ge_touch_info.x = ev->output.x;
152 ge_touch_info.y = ev->output.y;
154 if(ugd->ug_called_by_me == NULL)
156 edje_object_signal_emit(_EDJ(obj), "mouse,down,shrink", "bg");
157 ge_touch_info.b_pressed = true;
162 static Eina_Bool _ge_grid_clicked_timer_cb(void *data)
164 GE_CHECK_CANCEL(data);
165 ge_item *gitem = (ge_item *)data;
166 GE_CHECK_CANCEL(gitem->ugd);
167 ge_ugdata *ugd = gitem->ugd;
169 _ge_grid_icon_clicked(data, NULL, NULL);
171 GE_IF_DEL_TIMER(ugd->thumbs_clicked_timer)
173 return ECORE_CALLBACK_CANCEL;
177 static void _ge_grid_shrink_resp_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
182 ge_item *gitem = (ge_item *)data;
183 GE_CHECK(gitem->ugd);
184 /* ge_ugdata *ugd = gitem->ugd;
186 ugd->thumbs_clicked_timer = ecore_timer_add(GE_GIRD_ICON_CLICK_TIME_DELAY, _ge_grid_clicked_timer_cb, data);
188 _ge_grid_icon_clicked(data, obj, NULL);
190 edje_object_signal_callback_del(obj, "shrink,expand,done", "bg", _ge_grid_shrink_resp_cb);
193 static void _ge_grid_item_mouse_up(void *data, Evas *e, Evas_Object *obj, void *event_info)
196 Evas_Event_Mouse_Up *ev = event_info;
203 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD || ev->event_flags & EVAS_EVENT_FLAG_ON_SCROLL)
207 if((abs(ge_touch_info.x - ev->output.x) > GE_ITEM_MOUSE_UP_DISTANCE_X) || (abs(ge_touch_info.y - ev->output.y) > GE_ITEM_MOUSE_UP_DISTANCE_Y))
214 if(ge_touch_info.b_pressed)
216 edje_object_signal_emit(_EDJ(obj), "mouse,up,expand", "bg");
217 edje_object_signal_callback_add(_EDJ(obj), "shrink,expand,done", "bg", _ge_grid_shrink_resp_cb, data);
218 ge_touch_info.b_pressed = false;
223 if(ge_touch_info.b_pressed)
225 edje_object_signal_emit(_EDJ(obj), "mouse,up,expand", "bg");
226 ge_touch_info.b_pressed = false;
230 static void _ge_grid_check_changed(void *data, Evas_Object *obj, void *event_info)
235 ge_item *gitem = (ge_item *)data;
236 GE_CHECK(gitem->item);
237 GE_CHECK(gitem->item->file_url);
238 GE_CHECK(gitem->ugd);
239 ge_ugdata *ugd = gitem->ugd;
240 GE_CHECK(ugd->service);
242 if(_ge_get_view_mode() != GE_ThumbnailEdit_Mode)
244 //ge_dbgE("ViewMode.. now return.");
249 //ge_dbg("EditMode");
252 Eina_Bool checked = elm_check_state_get(obj);
255 if(ugd->file_select_mode == GE_File_Select_One) // add for one file selection
257 ge_dbg("Service add:%s", gitem->item->file_url);
258 /* Hide checked state in one file selection */
259 elm_check_state_set(obj, false);
261 service_add_extra_data(ugd->service,
262 GE_FILE_SELECT_RETURN_PATH,
263 gitem->item->file_url);
264 ug_send_result(ugd->ug, ugd->service);
265 ug_destroy_me(ugd->ug);
269 ge_dbg("Append:%s", gitem->item->file_url);
270 _ge_data_selected_list_append( gitem );
273 else if(ugd->file_select_mode != GE_File_Select_One)
275 ge_dbg("Remove:%s", gitem->item->file_url);
276 _ge_data_selected_list_remove( gitem );
279 if(ugd->file_select_mode != GE_File_Select_One)
281 gitem->checked = checked;
282 ge_ui_create_selinfo(ugd, ugd->thumbs_view_ly);
286 static Evas_Object *__ge_grid_get_content(void *data, Evas_Object *obj, const char *part)
291 ge_item *gitem = NULL;
292 bool is_expired_drm = false;
294 if(strlen(part) <= 0) {
295 ge_dbgE("part length <= 0");
299 gitem = (ge_item*)data;
300 GE_CHECK_NULL(gitem->item);
301 GE_CHECK_NULL(gitem->ugd);
302 ge_ugdata *ugd = gitem->ugd;
303 GE_CHECK_NULL(ugd->thumbs_view);
305 if (!g_strcmp0(part, "elm.swallow.icon")) {
306 Evas_Object *layout = NULL;
308 char *drm_path = NULL;
309 unsigned int orient = 0;
311 /* Is it DRM file? Has a valid RO? */
312 if(ge_drm_is_drm_file(gitem->item->file_url) &&
313 ge_drm_check_valid_ro(gitem->item->file_url, ge_drm_get_permtype(gitem->item->type)) == false) {
314 path = GE_DEFAULT_THUMB_ICON;;
315 is_expired_drm = true;
316 } else if (ge_grid_item_cnt < 2 &&
317 gitem->item->type == MEDIA_CONTENT_TYPE_IMAGE) {
318 if (!g_strcmp0(GE_DB_DEFAULT_THUMB, gitem->item->thumb_url)) {
319 path = GE_DEFAULT_THUMB_ICON;
321 char *drm_path = ge_drm_get_file_path(gitem);
322 path = _GETICON(drm_path);
323 if (_ge_is_image_valid(ugd, path) == false)
324 path = _GETICON(gitem->item->thumb_url);
325 #ifdef _USE_ROTATE_BG_GE
326 /* Rotate bg if it's created from original file */
327 if (!g_strcmp0(path, gitem->item->file_url))
328 _ge_exif_get_orientation(path, &orient);
333 ret = _ge_get_thumb(gitem->item->file_url,
334 &gitem->item->thumb_url);
335 /* Use default image */
337 path = GE_DEFAULT_THUMB_ICON;
339 path = gitem->item->thumb_url;
342 if(gitem->item->type == MEDIA_CONTENT_TYPE_VIDEO){
343 unsigned int v_dur = 0;
344 if (gitem->item->video_info) {
345 v_dur = gitem->item->video_info->duration;
348 if (gitem->item->video_info == NULL)
351 bk_len = gitem->item->video_info->bookmarks;
352 layout = _ge_thumb_show_part_icon_video(obj, path,
358 layout = _ge_thumb_show_part_icon_image(obj, path,
368 evas_object_event_callback_add(layout,
369 EVAS_CALLBACK_MOUSE_DOWN, _ge_grid_item_mouse_down, gitem);
370 evas_object_event_callback_add(layout,
371 EVAS_CALLBACK_MOUSE_UP, _ge_grid_item_mouse_up, gitem);
374 } else if (!g_strcmp0(part, "elm.swallow.end") &&
375 (_ge_get_view_mode() == GE_ThumbnailEdit_Mode)) {
376 Evas_Object* ck = NULL;
378 ck = elm_check_add(obj);
380 elm_object_style_set(ck, GE_CHECKBOX_STYLE_GRID);
381 evas_object_propagate_events_set(ck, EINA_FALSE);
383 gitem->check_obj = ck;
384 elm_check_state_set(ck, gitem->checked);
386 evas_object_smart_callback_add(ck, "changed",
387 _ge_grid_check_changed, data);
388 evas_object_show(ck);
396 static bool _ge_grid_create_thumb(ge_ugdata* ugd, Evas_Object* parent)
399 GE_CHECK_FALSE(parent);
402 ge_item* gitem = NULL;
403 int cnt = _ge_data_get_count_all();
405 ge_dbg("List count : %d", cnt);
407 gic.item_style = "thumbnail_view";
408 gic.func.text_get = NULL;
409 gic.func.content_get = __ge_grid_get_content;
411 elm_gengrid_clear(parent);
414 elm_object_theme_set(parent, ugd->th);
416 elm_object_style_set(parent, "gallery_efl/default");
418 for(i = 1; i <= cnt; i++)
420 _ge_data_get_item_by_index(&gitem, i);
421 if(gitem == NULL || gitem->item == NULL ||
422 gitem->item->uuid == NULL) {
423 ge_dbgE("Invalid gitem, continue...");
427 if(!gitem->item->file_url)
429 _ge_data_del_media_id(ugd, gitem->item->uuid);
430 _ge_data_item_list_remove(gitem);
436 /*if(_ge_get_view_mode() == GE_ThumbnailEdit_Mode)
438 ge_media_s *new_item = NULL;
439 _ge_local_data_get_media(gitem->item->uuid, &new_item);
442 ge_dbg("item or file doesn't exist, remove it...");
443 _ge_data_selected_list_remove(gitem);
444 _ge_data_item_list_remove(gitem);
448 _ge_data_type_free_geitem((void **)&new_item);
458 _ge_data_type_free_geitem((void **)&new_item);
463 gitem->elm_item = elm_gengrid_item_append(parent, &gic, gitem, _ge_grid_sel, gitem);
464 gitem->check_obj = NULL;
469 elm_gengrid_select_mode_set(parent, ELM_OBJECT_SELECT_MODE_NONE);
470 ge_grid_item_cnt = item_cnt;
481 Evas_Object* ge_grid_create_ly(Evas_Object* parent)
484 GE_CHECK_NULL(parent);
485 Evas_Object* layout = NULL;
487 layout = ge_ui_load_edj(parent, GE_EDJ_FILE, GE_GRP_GRIDVIEW);
488 GE_CHECK_NULL(layout);
489 evas_object_show (layout);
494 int ge_grid_del_callbacks(ge_ugdata *ugd)
496 GE_CHECK_VAL(ugd, -1);
499 ge_dbg("Delete thumbnails callbacks!");
500 evas_object_smart_callback_del(ugd->thumbs_view, "selected", _ge_grid_selected);
501 evas_object_smart_callback_del(ugd->thumbs_view, "unselected", _ge_grid_unselected);
502 evas_object_smart_callback_del(ugd->thumbs_view, "clicked", _ge_grid_clicked);
503 evas_object_smart_callback_del(ugd->thumbs_view, "longpressed", _ge_grid_longpress);
504 evas_object_smart_callback_del(ugd->thumbs_view, "drag,start,up", _ge_grid_drag_up);
505 evas_object_smart_callback_del(ugd->thumbs_view, "drag,start,right", _ge_grid_drag_right);
506 evas_object_smart_callback_del(ugd->thumbs_view, "drag,start,down", _ge_grid_drag_down);
507 evas_object_smart_callback_del(ugd->thumbs_view, "drag,start,left", _ge_grid_drag_left);
508 evas_object_smart_callback_del(ugd->thumbs_view, "drag,stop", _ge_grid_drag_stop);
514 * When select album, show first (GE_FIRST_VIEW_END_POS+1) medias.
515 * Then use idler to get other medias from DB and appened
517 * In order to reduce transit time of first show of thumbnails view.
518 * Cause most of time is spent for getting records from DB,
519 * so we get first (GE_FIRST_VIEW_END_POS+1) items and show thumbnails view,
520 * it will accelerate view show.
522 int ge_grid_idler_append_thumbs(void* data)
524 GE_CHECK_VAL(data, -1);
525 ge_ugdata *ugd = (ge_ugdata *)data;
526 GE_CHECK_VAL(ugd->thumbs_view, -1);
529 ge_item* gitem = NULL;
530 /* Get all medias count of current album */
531 int cnt = _ge_data_get_count_all();
533 ge_cluster* cur_album = _ge_get_current_album();
534 GE_CHECK_VAL(cur_album, -1);
535 GE_CHECK_VAL(cur_album->cluster, -1);
536 ge_dbg("First view medias count: %d;", cnt);
538 if(cnt != (GE_FIRST_VIEW_END_POS+1))
540 ge_dbg("No any more items, return!");
543 /* Get other items from DB */
544 ret = _ge_data_get_items_list(ugd, cur_album, (GE_FIRST_VIEW_END_POS+1),
545 GE_GET_UNTIL_LAST_RECORD);
546 ge_dbgW("###Get items list over[%d]###", ret);
548 ge_dbg("Get items list failed!");
552 cnt = _ge_data_get_count_all();
553 ge_dbg("Grid view all medias count: %d", cnt);
556 /* From (GL_FIRST_VIEW_END_POS + 2)th item to last one */
557 i = GE_FIRST_VIEW_END_POS + 2;
561 _ge_data_get_item_by_index(&gitem, i);
562 if(gitem == NULL || gitem->item == NULL ||
563 gitem->item->uuid == NULL) {
564 ge_dbgE("Invalid gitem, continue...");
568 if(!gitem->item->file_url)
570 ge_dbg("file_url is invalid.");
571 _ge_data_del_media_id(ugd, gitem->item->uuid);
572 _ge_data_selected_list_remove(gitem);
573 _ge_data_item_list_remove(gitem);
580 gitem->elm_item = elm_gengrid_item_append(ugd->thumbs_view, &gic, gitem, _ge_grid_sel, gitem);
584 ge_dbg("\n\n<<<<<<<<Use idler to append other medias--Done<<<<<<<<<\n");
591 ge_grid_item_cnt = item_cnt + GE_FIRST_VIEW_END_POS + 1;
592 ge_dbg("All count appended: %d", ge_grid_item_cnt);
597 Evas_Object* ge_grid_create_view(ge_ugdata* ugd, Evas_Object* parent)
600 GE_CHECK_NULL(parent);
605 Evas_Object *grid = elm_gengrid_add(parent);
607 double scale_factor = ugd->win_scale;
608 item_w = (int)(GE_GRID_ITEM_SIZE_W * scale_factor);
609 item_h = (int)(GE_GRID_ITEM_SIZE_H * scale_factor);
610 icon_size = (int)(GE_GRID_ICON_SIZE * scale_factor);
611 ge_dbg("Own scale: %f, elm_config_scale_get =%f", scale_factor, elm_config_scale_get());
613 if(!_ge_grid_create_thumb(ugd, grid)) {
614 evas_object_del(grid);
617 ugd->nocontents = ge_ui_create_nocontents(ugd);
618 evas_object_show (ugd->nocontents);
620 return ugd->nocontents;
622 ge_dbg("ge_grid_item_cnt : %d", ge_grid_item_cnt);
623 if(ge_grid_item_cnt == GE_GRID_ITEM_ZOOM_LEVEL_01_CNT) {
624 item_w *= GE_GRID_ITEM_ZOOM_LEVEL_01;
625 item_h *= GE_GRID_ITEM_ZOOM_LEVEL_01;
626 icon_size *= GE_GRID_ITEM_ZOOM_LEVEL_01;
627 } else if(ge_grid_item_cnt <= GE_GRID_ITEM_ZOOM_LEVEL_02_CNT) {
628 item_w *= GE_GRID_ITEM_ZOOM_LEVEL_02;
629 item_h *= GE_GRID_ITEM_ZOOM_LEVEL_02;
630 icon_size *= GE_GRID_ITEM_ZOOM_LEVEL_02;
633 ugd->icon_size = icon_size;
634 evas_object_show (grid);
638 elm_gengrid_item_size_set(grid, item_w, item_h);
639 ge_dbg("Gengrid item w: %d, h: %d.", item_w, item_h);
640 elm_gengrid_align_set(grid, 0.5, 0.0);
641 elm_gengrid_horizontal_set(grid, EINA_FALSE);
642 elm_gengrid_bounce_set(grid, EINA_FALSE, EINA_TRUE);
643 elm_gengrid_multi_select_set(grid, EINA_TRUE);
645 evas_object_smart_callback_add(grid, "selected", _ge_grid_selected, NULL);
646 evas_object_smart_callback_add(grid, "unselected", _ge_grid_unselected, NULL);
647 evas_object_smart_callback_add(grid, "clicked", _ge_grid_clicked, NULL);
648 evas_object_smart_callback_add(grid, "longpressed", _ge_grid_longpress, NULL);
649 evas_object_smart_callback_add(grid, "drag,start,up", _ge_grid_drag_up, NULL);
650 evas_object_smart_callback_add(grid, "drag,start,right", _ge_grid_drag_right, NULL);
651 evas_object_smart_callback_add(grid, "drag,start,down", _ge_grid_drag_down, NULL);
652 evas_object_smart_callback_add(grid, "drag,start,left", _ge_grid_drag_left, NULL);
653 evas_object_smart_callback_add(grid, "drag,stop", _ge_grid_drag_stop, NULL);
654 evas_object_size_hint_weight_set(grid, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
659 int ge_grid_clear_view(ge_ugdata *ugd)
661 GE_CHECK_VAL(ugd, -1);
662 if(ugd->file_select_mode == GE_File_Select_One)
664 service_remove_extra_data(ugd->service,
665 GE_FILE_SELECT_RETURN_PATH);
670 if(ugd->thumbs_nocontents != ugd->thumbs_view)
671 ge_grid_del_callbacks(ugd);
673 evas_object_del(ugd->thumbs_view);
674 ugd->thumbs_view = NULL;
675 ugd->thumbs_nocontents = NULL;
676 ugd->thumbs_nf_it = NULL;
681 int ge_grid_update_view(ge_ugdata *ugd)
684 GE_CHECK_VAL(ugd, -1);
685 if(_ge_grid_create_thumb(ugd, ugd->thumbs_view) == EINA_FALSE) {
686 ge_grid_del_callbacks(ugd);
688 double scale_factor = ugd->win_scale;
689 int item_w = (int)(GE_GRID_ITEM_SIZE_W * scale_factor);
690 int item_h = (int)(GE_GRID_ITEM_SIZE_H * scale_factor);
691 int icon_size = (int)(GE_GRID_ICON_SIZE * scale_factor);
693 ge_dbg("ge_grid_item_cnt : %d", ge_grid_item_cnt);
694 if(ge_grid_item_cnt == GE_GRID_ITEM_ZOOM_LEVEL_01_CNT) {
695 item_w *= GE_GRID_ITEM_ZOOM_LEVEL_01;
696 item_h *= GE_GRID_ITEM_ZOOM_LEVEL_01;
697 icon_size *= GE_GRID_ITEM_ZOOM_LEVEL_01;
698 } else if(ge_grid_item_cnt <= GE_GRID_ITEM_ZOOM_LEVEL_02_CNT) {
699 item_w *= GE_GRID_ITEM_ZOOM_LEVEL_02;
700 item_h *= GE_GRID_ITEM_ZOOM_LEVEL_02;
701 icon_size *= GE_GRID_ITEM_ZOOM_LEVEL_02;
704 ugd->icon_size = icon_size;
705 elm_gengrid_item_size_set(ugd->thumbs_view, item_w, item_h);