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"
22 #include "ge-db-handler.h"
23 #include "ge-strings.h"
25 /* Icon swallowed to part "elm.swallow.icon" */
26 #define GE_GRID_ICON_SIZE 156
27 #define GE_ITEM_MOUSE_UP_DISTANCE_X 20
28 #define GE_ITEM_MOUSE_UP_DISTANCE_Y 20
29 #define GE_GIRD_ICON_CLICK_TIME_DELAY 0.01f
31 static Elm_Gengrid_Item_Class gic;
32 static int ge_grid_item_cnt = 0;
41 static ge_grid_touch_info ge_touch_info;
43 static void _ge_grid_drag_up(void *data, Evas_Object *obj, void *event_info)
48 static void _ge_grid_drag_right(void *data, Evas_Object *obj, void *event_info)
53 static void _ge_grid_drag_down(void *data, Evas_Object *obj, void *event_info)
58 static void _ge_grid_drag_left(void *data, Evas_Object *obj, void *event_info)
63 static void _ge_grid_drag_stop(void *data, Evas_Object *obj, void *event_info)
68 static void _ge_grid_selected(void *data, Evas_Object *obj, void *event_info)
73 static void _ge_grid_unselected(void *data, Evas_Object *obj, void *event_info)
78 static void _ge_grid_clicked(void *data, Evas_Object *obj, void *event_info)
83 static void _ge_grid_longpress(void *data, Evas_Object *obj, void *event_info)
88 static void _ge_grid_sel(void *data, Evas_Object *obj, void *event_info)
92 if(_ge_get_view_mode() != GE_ThumbnailView_Mode)
94 //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)
109 ge_dbgE("file_url is invalid!");
114 ge_dbg("file_url: %s.", gitem->item->file_url);
117 if(ugd->file_select_mode == GE_File_Select_Setas)//imageviewer only supprot image type while setting wallpaper
119 if(gitem->item->type == MINFO_ITEM_IMAGE)
121 _ge_set_current_item(gitem);
122 ge_dbg("Loading UG-IMAGE(VIDEO)-VIEWER");
123 ge_ext_load_iv_ug(ugd);
125 else if(gitem->item->type == MINFO_ITEM_VIDEO && ugd->popup == NULL)
127 ge_ui_create_popup(ugd, GE_Popup_OneButton, GE_POPUP_ONLY_SUPPORT_IMAGE);
131 else if(gitem->item->type == MINFO_ITEM_IMAGE || gitem->item->type == MINFO_ITEM_VIDEO)
133 _ge_set_current_item(gitem);
134 ge_dbg("Loading UG-IMAGE(VIDEO)-VIEWER");
135 ge_ext_load_iv_ug(ugd);
139 static void _ge_grid_icon_clicked(void *data, Evas_Object *obj, void *event_info)
143 _ge_grid_sel(data, obj, event_info);
146 static void _ge_grid_item_mouse_down(void *data, Evas *e, Evas_Object *obj, void *event_info)
148 Evas_Event_Mouse_Down *ev = (Evas_Event_Mouse_Down*)event_info;
153 ge_item *gitem = (ge_item *)data;
154 GE_CHECK(gitem->ugd);
155 ge_ugdata *ugd = gitem->ugd;
157 ge_touch_info.x = ev->output.x;
158 ge_touch_info.y = ev->output.y;
160 if(ugd->ug_called_by_me == NULL)
162 edje_object_signal_emit(_EDJ(obj), "mouse,down,shrink", "bg");
163 ge_touch_info.b_pressed = true;
168 static void _ge_grid_shrink_resp_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
173 ge_item *gitem = (ge_item *)data;
174 GE_CHECK(gitem->ugd);
175 _ge_grid_icon_clicked(data, obj, NULL);
177 edje_object_signal_callback_del(obj, "shrink,expand,done", "bg", _ge_grid_shrink_resp_cb);
180 static void _ge_grid_item_mouse_up(void *data, Evas *e, Evas_Object *obj, void *event_info)
183 Evas_Event_Mouse_Up *ev = event_info;
190 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD || ev->event_flags & EVAS_EVENT_FLAG_ON_SCROLL)
194 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))
201 if(ge_touch_info.b_pressed)
203 edje_object_signal_emit(_EDJ(obj), "mouse,up,expand", "bg");
204 edje_object_signal_callback_add(_EDJ(obj), "shrink,expand,done", "bg", _ge_grid_shrink_resp_cb, data);
205 ge_touch_info.b_pressed = false;
210 if(ge_touch_info.b_pressed)
212 edje_object_signal_emit(_EDJ(obj), "mouse,up,expand", "bg");
213 ge_touch_info.b_pressed = false;
217 static void _ge_grid_check_changed(void *data, Evas_Object *obj, void *event_info)
222 ge_item *gitem = (ge_item *)data;
223 GE_CHECK(gitem->item);
224 GE_CHECK(gitem->item->file_url);
225 GE_CHECK(gitem->ugd);
226 ge_ugdata *ugd = gitem->ugd;
228 if(_ge_get_view_mode() != GE_ThumbnailEdit_Mode)
231 Eina_Bool checked = elm_check_state_get(obj);
234 if(ugd->file_select_mode == GE_File_Select_One) // add for one file selection
236 ge_dbg("Bundle add:%s", gitem->item->file_url);
237 /* Hide checked state in one file selection */
238 elm_check_state_set(obj, false);
240 bundle_del(ugd->bundle, GE_FILE_SELECT_RETURN_PATH);
241 bundle_add(ugd->bundle, GE_FILE_SELECT_RETURN_PATH, gitem->item->file_url);
242 ug_send_result(ugd->ug, ugd->bundle);
243 ug_destroy_me(ugd->ug);
247 ge_dbg("Append:%s", gitem->item->file_url);
248 ge_db_selected_list_append( gitem );
251 else if(ugd->file_select_mode != GE_File_Select_One)
253 ge_dbg("Remove:%s", gitem->item->file_url);
254 ge_db_selected_list_remove( gitem );
257 if(ugd->file_select_mode != GE_File_Select_One)
259 gitem->checked = checked;
260 ge_ui_create_selinfo(ugd, ugd->thumbs_view_ly);
264 Evas_Object *_ge_grid_get_content(void *data, Evas_Object *obj, const char *part)
269 ge_item *gitem = NULL;
271 if(strlen(part) <= 0)
273 ge_dbgE("part length <= 0");
277 gitem = (ge_item*)data;
278 GE_CHECK_NULL(gitem->item);
279 GE_CHECK_NULL(gitem->ugd);
280 ge_ugdata *ugd = gitem->ugd;
282 if (!strcmp(part, "elm.swallow.icon"))
284 Evas_Object *layout = elm_layout_add(obj);
285 GE_CHECK_NULL(layout);
286 Evas_Object *bg = elm_bg_add(obj);
288 elm_bg_load_size_set(bg, ugd->icon_size, ugd->icon_size);
290 elm_bg_file_set(bg, _GETICON(gitem->item->thumb_url), NULL);
291 evas_object_size_hint_max_set(bg, ugd->icon_size,
293 evas_object_size_hint_aspect_set(bg, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
294 evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
295 evas_object_size_hint_align_set(bg, EVAS_HINT_FILL, EVAS_HINT_FILL);
297 if(gitem->item->type == MINFO_ITEM_VIDEO)
303 elm_object_theme_set(layout, ugd->th);
305 elm_layout_theme_set(layout, "gengrid", "photoframe", "default_layout_video");
306 elm_object_part_content_set(layout, "elm.swallow.icon", bg);
308 // Set bookmark icon.
309 if(gitem->item->meta_info == NULL || gitem->item->meta_info->video_info == NULL)
315 bk_len = g_list_length(gitem->item->meta_info->video_info->bookmarks);
320 elm_layout_theme_set(layout, "gengrid", "photoframe", "default_layout_video_bookmark");
324 elm_layout_theme_set(layout, "gengrid", "photoframe", "default_layout_video");
326 elm_object_part_content_set(layout, "elm.swallow.icon", bg);
328 /* Set bookmark icon */
331 Evas_Object *icon = elm_icon_add(obj);
333 elm_icon_file_set(icon, GE_THUMB_BOOKMARK, NULL);
334 evas_object_show(icon);
335 elm_object_part_content_set(layout, "elm.swallow.bookmarkicon", icon);
338 /* Running time of the video */
339 if(gitem->item->meta_info && gitem->item->meta_info->video_info)
341 char ret_str[GE_VIDEO_DURATION_MAX]={0,};
342 /* Convert time unit form millisecond to second */
343 int duration = floor((gitem->item->meta_info->video_info->duration) / GE_TIME_SECOND_MILLISECOND);
349 if(duration >= GE_TIME_HOUR_SECOND)
351 /* It's equal or greater than 1 hour */
352 dur_sec = duration % GE_TIME_MINUTE_SECOND;
353 tmp = floor(duration / GE_TIME_MINUTE_SECOND);
354 dur_min = tmp % GE_TIME_HOUR_MINUTE;
355 dur_hr = floor(tmp / GE_TIME_HOUR_MINUTE);
357 else if(duration >= GE_TIME_MINUTE_SECOND)
359 /* It's equal or greater than 1 minute */
361 dur_min = floor(duration / GE_TIME_MINUTE_SECOND);
362 dur_sec = duration % GE_TIME_MINUTE_SECOND;
368 dur_sec = duration % GE_TIME_MINUTE_SECOND;
371 snprintf(ret_str, sizeof(ret_str), "%02d:%02d:%02d", dur_hr, dur_min, dur_sec);
372 ret_str[strlen(ret_str)] = '\0';
373 elm_object_part_text_set(layout, "elm.text", ret_str);
380 elm_object_theme_set(layout, ugd->th);
383 elm_layout_theme_set(layout, "gengrid", "photoframe", "default_layout");
384 elm_object_part_content_set(layout, "elm.swallow.icon", bg);
387 evas_object_event_callback_add(layout, EVAS_CALLBACK_MOUSE_DOWN, _ge_grid_item_mouse_down, gitem);
388 evas_object_event_callback_add(layout, EVAS_CALLBACK_MOUSE_UP, _ge_grid_item_mouse_up, gitem);
389 evas_object_show(layout);
393 else if (!strcmp(part, "elm.swallow.end") && (_ge_get_view_mode() == GE_ThumbnailEdit_Mode))
395 Evas_Object* ck = NULL;
397 ck = elm_check_add(obj);
399 elm_object_style_set(ck, GE_CHECKBOX_STYLE_GRID);
400 evas_object_propagate_events_set(ck, EINA_FALSE);
402 gitem->check_obj = ck;
403 elm_check_state_set(ck, gitem->checked);
405 evas_object_smart_callback_add(ck, "changed", _ge_grid_check_changed, data);
406 evas_object_show(ck);
414 static bool _ge_grid_create_thumb(ge_ugdata* ugd, Evas_Object* parent)
417 GE_CHECK_FALSE(parent);
420 ge_item* gitem = NULL;
421 int cnt = ge_db_get_count_all();
423 ge_dbg("List count : %d", cnt);
425 gic.item_style = "thumbnail_view";
426 gic.func.text_get = NULL;
427 gic.func.content_get = _ge_grid_get_content;
429 elm_gengrid_clear(parent);
432 elm_object_theme_set(parent, ugd->th);
434 elm_object_style_set(parent, "gallery_efl/default");
436 for(i = 1; i <= cnt; i++)
438 ge_db_get_item_by_index(&gitem, i);
439 if(gitem == NULL || gitem->item == NULL ||
440 gitem->item->uuid == NULL) {
441 ge_dbgE("Invalid gitem, continue...");
445 if(!gitem->item->file_url)
447 ge_db_del_media_id(ugd, gitem->item->uuid);
448 ge_db_item_list_remove(gitem);
454 if(_ge_get_view_mode() == GE_ThumbnailEdit_Mode)
456 Mitem* new_item = ge_db_new_mitem(ugd, gitem->item->uuid);
457 if(!new_item || !ecore_file_exists(gitem->item->file_url))
459 ge_dbg("item or file doesn't exist, remove it...");
460 ge_db_selected_list_remove(gitem);
461 ge_db_item_list_remove(gitem);
465 ge_db_destroy_mtype_item(new_item);
475 ge_db_destroy_mtype_item(new_item);
480 gitem->elm_item = elm_gengrid_item_append(parent, &gic, gitem, _ge_grid_sel, gitem);
481 gitem->check_obj = NULL;
486 elm_gengrid_select_mode_set(parent, ELM_OBJECT_SELECT_MODE_NONE);
487 ge_grid_item_cnt = item_cnt;
498 Evas_Object* ge_grid_create_ly(Evas_Object* parent)
501 GE_CHECK_NULL(parent);
502 Evas_Object* layout = NULL;
504 layout = ge_ui_load_edj(parent, GE_EDJ_FILE, GE_GRP_GRIDVIEW);
505 GE_CHECK_NULL(layout);
506 evas_object_show (layout);
511 int ge_grid_del_callbacks(ge_ugdata *ugd)
513 GE_CHECK_VAL(ugd, -1);
516 ge_dbg("Delete thumbnails callbacks!");
517 evas_object_smart_callback_del(ugd->thumbs_view, "selected", _ge_grid_selected);
518 evas_object_smart_callback_del(ugd->thumbs_view, "unselected", _ge_grid_unselected);
519 evas_object_smart_callback_del(ugd->thumbs_view, "clicked", _ge_grid_clicked);
520 evas_object_smart_callback_del(ugd->thumbs_view, "longpressed", _ge_grid_longpress);
521 evas_object_smart_callback_del(ugd->thumbs_view, "drag,start,up", _ge_grid_drag_up);
522 evas_object_smart_callback_del(ugd->thumbs_view, "drag,start,right", _ge_grid_drag_right);
523 evas_object_smart_callback_del(ugd->thumbs_view, "drag,start,down", _ge_grid_drag_down);
524 evas_object_smart_callback_del(ugd->thumbs_view, "drag,start,left", _ge_grid_drag_left);
525 evas_object_smart_callback_del(ugd->thumbs_view, "drag,stop", _ge_grid_drag_stop);
531 * When select album, show first (GE_FIRST_VIEW_END_POS+1) medias.
532 * Then use idler to get other medias from DB and appened
534 * In order to reduce transit time of first show of thumbnails view.
535 * Cause most of time is spent for getting records from DB,
536 * so we get first (GE_FIRST_VIEW_END_POS+1) items and show thumbnails view,
537 * it will accelerate view show.
539 int ge_grid_idler_append_thumbs(void* data)
541 GE_CHECK_VAL(data, -1);
542 ge_ugdata *ugd = (ge_ugdata *)data;
543 GE_CHECK_VAL(ugd->thumbs_view, -1);
546 ge_item* gitem = NULL;
547 /* Get all medias count of current album */
548 int cnt = ge_db_get_count_all();
550 ge_cluster* cur_album = _ge_get_current_album();
551 GE_CHECK_VAL(cur_album, -1);
552 GE_CHECK_VAL(cur_album->cluster, -1);
553 ge_dbg("First view medias count: %d;", cnt);
555 if(cnt != (GE_FIRST_VIEW_END_POS+1))
557 ge_dbg("No any more items, return!");
560 /* Get other items from DB */
561 ret = ge_db_get_items_list(ugd, cur_album, (GE_FIRST_VIEW_END_POS+1), GE_GET_UNTIL_LAST_RECORD);
562 ge_dbg("\n\n############ge_db_get_items_list Error code: %d#################\n", ret);
565 ge_dbg("ge_db_get_items_list ERROR, return!");
569 cnt = ge_db_get_count_all();
570 ge_dbg("Grid view all medias count: %d", cnt);
573 /* From (GL_FIRST_VIEW_END_POS + 2)th item to last one */
574 i = GE_FIRST_VIEW_END_POS + 2;
578 ge_db_get_item_by_index(&gitem, i);
579 if(gitem == NULL || gitem->item == NULL ||
580 gitem->item->uuid == NULL) {
581 ge_dbgE("Invalid gitem, continue...");
585 if(!gitem->item->file_url)
587 ge_dbg("file_url is invalid.");
588 ge_db_del_media_id(ugd, gitem->item->uuid);
589 ge_db_selected_list_remove(gitem);
590 ge_db_item_list_remove(gitem);
597 gitem->elm_item = elm_gengrid_item_append(ugd->thumbs_view, &gic, gitem, _ge_grid_sel, gitem);
601 ge_dbg("\n\n<<<<<<<<Use idler to append other medias--Done<<<<<<<<<\n");
608 ge_grid_item_cnt = item_cnt + GE_FIRST_VIEW_END_POS + 1;
609 ge_dbg("All count appended: %d", ge_grid_item_cnt);
614 Evas_Object* ge_grid_create_view(ge_ugdata* ugd, Evas_Object *parent)
617 GE_CHECK_NULL(parent);
622 Evas_Object *grid = elm_gengrid_add(parent);
624 double scale_factor = ugd->win_scale;
625 item_w = (int)(GE_GRID_ITEM_SIZE_W * scale_factor);
626 item_h = (int)(GE_GRID_ITEM_SIZE_H * scale_factor);
627 icon_size = (int)(GE_GRID_ICON_SIZE * scale_factor);
628 ge_dbg("Own scale: %f, elm_config_scale_get =%f", scale_factor, elm_config_scale_get());
630 if(!_ge_grid_create_thumb(ugd, grid)) {
631 evas_object_del(grid);
634 ugd->nocontents = ge_ui_create_nocontents(ugd);
635 evas_object_show (ugd->nocontents);
637 return ugd->nocontents;
639 ge_dbg("ge_grid_item_cnt : %d", ge_grid_item_cnt);
640 if(ge_grid_item_cnt == GE_GRID_ITEM_ZOOM_LEVEL_01_CNT) {
641 item_w *= GE_GRID_ITEM_ZOOM_LEVEL_01;
642 item_h *= GE_GRID_ITEM_ZOOM_LEVEL_01;
643 icon_size *= GE_GRID_ITEM_ZOOM_LEVEL_01;
644 } else if(ge_grid_item_cnt <= GE_GRID_ITEM_ZOOM_LEVEL_02_CNT) {
645 item_w *= GE_GRID_ITEM_ZOOM_LEVEL_02;
646 item_h *= GE_GRID_ITEM_ZOOM_LEVEL_02;
647 icon_size *= GE_GRID_ITEM_ZOOM_LEVEL_02;
650 ugd->icon_size = icon_size;
651 evas_object_show (grid);
655 elm_gengrid_item_size_set(grid, item_w, item_h);
656 ge_dbg("Gengrid item w: %d, h: %d.", item_w, item_h);
657 elm_gengrid_align_set(grid, 0.5, 0.0);
658 elm_gengrid_horizontal_set(grid, EINA_FALSE);
659 elm_gengrid_bounce_set(grid, EINA_FALSE, EINA_TRUE);
660 elm_gengrid_multi_select_set(grid, EINA_TRUE);
662 evas_object_smart_callback_add(grid, "selected", _ge_grid_selected, NULL);
663 evas_object_smart_callback_add(grid, "unselected", _ge_grid_unselected, NULL);
664 evas_object_smart_callback_add(grid, "clicked", _ge_grid_clicked, NULL);
665 evas_object_smart_callback_add(grid, "longpressed", _ge_grid_longpress, NULL);
666 evas_object_smart_callback_add(grid, "drag,start,up", _ge_grid_drag_up, NULL);
667 evas_object_smart_callback_add(grid, "drag,start,right", _ge_grid_drag_right, NULL);
668 evas_object_smart_callback_add(grid, "drag,start,down", _ge_grid_drag_down, NULL);
669 evas_object_smart_callback_add(grid, "drag,start,left", _ge_grid_drag_left, NULL);
670 evas_object_smart_callback_add(grid, "drag,stop", _ge_grid_drag_stop, NULL);
671 evas_object_size_hint_weight_set(grid, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
676 int ge_grid_clear_view(ge_ugdata *ugd)
678 GE_CHECK_VAL(ugd, -1);
679 if(ugd->file_select_mode == GE_File_Select_One)
681 bundle_del(ugd->bundle, GE_FILE_SELECT_RETURN_PATH);
686 if(ugd->thumbs_nocontents != ugd->thumbs_view)
687 ge_grid_del_callbacks(ugd);
689 evas_object_del(ugd->thumbs_view);
690 ugd->thumbs_view = NULL;
691 ugd->thumbs_nocontents = NULL;
692 ugd->thumbs_nf_it = NULL;
697 int ge_grid_update_view(ge_ugdata *ugd)
700 GE_CHECK_VAL(ugd, -1);
701 if(_ge_grid_create_thumb(ugd, ugd->thumbs_view) == EINA_FALSE) {
702 ge_grid_del_callbacks(ugd);
704 double scale_factor = ugd->win_scale;
705 int item_w = (int)(GE_GRID_ITEM_SIZE_W * scale_factor);
706 int item_h = (int)(GE_GRID_ITEM_SIZE_H * scale_factor);
707 int icon_size = (int)(GE_GRID_ICON_SIZE * scale_factor);
709 ge_dbg("ge_grid_item_cnt : %d", ge_grid_item_cnt);
710 if(ge_grid_item_cnt == GE_GRID_ITEM_ZOOM_LEVEL_01_CNT) {
711 item_w *= GE_GRID_ITEM_ZOOM_LEVEL_01;
712 item_h *= GE_GRID_ITEM_ZOOM_LEVEL_01;
713 icon_size *= GE_GRID_ITEM_ZOOM_LEVEL_01;
714 } else if(ge_grid_item_cnt <= GE_GRID_ITEM_ZOOM_LEVEL_02_CNT) {
715 item_w *= GE_GRID_ITEM_ZOOM_LEVEL_02;
716 item_h *= GE_GRID_ITEM_ZOOM_LEVEL_02;
717 icon_size *= GE_GRID_ITEM_ZOOM_LEVEL_02;
720 ugd->icon_size = icon_size;
721 elm_gengrid_item_size_set(ugd->thumbs_view, item_w, item_h);