From e171ee1cb60faae6e9c8e842f5a9d0f00fc30684 Mon Sep 17 00:00:00 2001 From: Stephen okra Houston Date: Mon, 15 Aug 2016 12:36:50 -0500 Subject: [PATCH] Ephoto: Add back in sorting by image similarity, this time with the crashing and bugs eliminated. --- src/bin/ephoto.h | 8 +- src/bin/ephoto_main.c | 91 ++++++++++---------- src/bin/ephoto_thumb_browser.c | 151 +++++++++++++++++++++++++++++++-- 3 files changed, 193 insertions(+), 57 deletions(-) diff --git a/src/bin/ephoto.h b/src/bin/ephoto.h index 9bc1fe2..f9aff91 100644 --- a/src/bin/ephoto.h +++ b/src/bin/ephoto.h @@ -55,8 +55,7 @@ Evas_Object *ephoto_window_add(const char *path); void ephoto_title_set(Ephoto *ephoto, const char *title); void ephoto_thumb_size_set(Ephoto *ephoto, int size); Evas_Object *ephoto_thumb_add(Ephoto *ephoto, Evas_Object *parent, - const char *path); -void ephoto_thumb_path_set(Evas_Object *obj, const char *path); + Ephoto_Entry *entry); void ephoto_directory_set(Ephoto *ephoto, const char *path, Elm_Object_Item *expanded, Eina_Bool dirs_only, Eina_Bool thumbs_only); void ephoto_show_folders(Ephoto *ephoto, Eina_Bool toggle); @@ -202,7 +201,8 @@ enum _Ephoto_Sort EPHOTO_SORT_ALPHABETICAL_ASCENDING, EPHOTO_SORT_ALPHABETICAL_DESCENDING, EPHOTO_SORT_MODTIME_ASCENDING, - EPHOTO_SORT_MODTIME_DESCENDING + EPHOTO_SORT_MODTIME_DESCENDING, + EPHOTO_SORT_SIMILARITY }; enum _Ephoto_Ipc_Domain @@ -308,6 +308,7 @@ struct _Ephoto_Entry const char *path; const char *basename; const char *label; + const char *sort_id; double size; Ephoto *ephoto; Eio_Monitor *monitor; @@ -319,6 +320,7 @@ struct _Ephoto_Entry Eina_Bool is_link; Eina_Bool no_delete; Evas_Object *genlist; + Evas_Object *thumb; }; struct _Ephoto_Event_Entry_Create diff --git a/src/bin/ephoto_main.c b/src/bin/ephoto_main.c index 50c212e..b765965 100644 --- a/src/bin/ephoto_main.c +++ b/src/bin/ephoto_main.c @@ -991,54 +991,78 @@ ephoto_thumb_size_set(Ephoto *ephoto, int size) ecore_timer_add(0.1, _thumb_gen_size_changed_timer_cb, ephoto); } +static void +_thumb_gen_cb(void *data, Evas_Object *obj EINA_UNUSED, + void *event_data EINA_UNUSED) +{ + Ephoto_Entry *entry = data; + const char *id; + + if (!entry) + return; + + id = e_thumb_sort_id_get(entry->thumb); + e_thumb_icon_end(entry->thumb); + if (!id || entry->sort_id) + return; + + if (entry->sort_id) + eina_stringshare_replace(&entry->sort_id, id); + else + entry->sort_id = eina_stringshare_add(id); +} + static void _thumb_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED) { Ephoto *ephoto = data; - e_thumb_icon_end(obj); ephoto->thumbs = eina_list_remove(ephoto->thumbs, obj); } Evas_Object * -ephoto_thumb_add(Ephoto *ephoto, Evas_Object *parent, const char *path) +ephoto_thumb_add(Ephoto *ephoto, Evas_Object *parent, Ephoto_Entry *entry) { - Evas_Object *o; + Evas_Object *o = NULL; - if (path) + if (entry->path) { - const char *ext = strrchr(path, '.'); + const char *ext = strrchr(entry->path, '.'); if (ext) { ext++; if ((strcasecmp(ext, "edj") == 0)) { + const char *group = NULL; + o = elm_icon_add(parent); - } - else - { - o = e_thumb_icon_add(parent); - e_thumb_icon_file_set(o, path, NULL); - e_thumb_icon_size_set(o, ephoto->thumb_gen_size, - ephoto->thumb_gen_size); - e_thumb_icon_begin(o); + if (edje_file_group_exists(entry->path, "e/desktop/background")) + group = "e/desktop/background"; + else + { + Eina_List *g = edje_file_collection_list(entry->path); + + group = eina_list_data_get(g); + edje_file_collection_list_free(g); + } + elm_image_file_set(o, entry->path, group); } } - else + if (!o) { o = e_thumb_icon_add(parent); - e_thumb_icon_file_set(o, path, NULL); + evas_object_smart_callback_add(o, "e_thumb_gen", _thumb_gen_cb, entry); + e_thumb_icon_file_set(o, entry->path, NULL); e_thumb_icon_size_set(o, ephoto->thumb_gen_size, ephoto->thumb_gen_size); e_thumb_icon_begin(o); + entry->thumb = o; } } else - o = e_thumb_icon_add(parent); - if (!o) - return NULL; + return NULL; ephoto->thumbs = eina_list_append(ephoto->thumbs, o); evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _thumb_del, ephoto); @@ -1046,34 +1070,6 @@ ephoto_thumb_add(Ephoto *ephoto, Evas_Object *parent, const char *path) return o; } -void -ephoto_thumb_path_set(Evas_Object *obj, const char *path) -{ - const char *group = NULL; - const char *ext = strrchr(path, '.'); - - if (ext) - { - ext++; - if ((strcasecmp(ext, "edj") == 0)) - { - if (edje_file_group_exists(path, "e/desktop/background")) - group = "e/desktop/background"; - else - { - Eina_List *g = edje_file_collection_list(path); - - group = eina_list_data_get(g); - edje_file_collection_list_free(g); - } - elm_image_file_set(obj, path, group); - return; - } - } - e_thumb_icon_file_set(obj, path, group); - e_thumb_icon_begin(obj); -} - Ephoto_Entry * ephoto_entry_new(Ephoto *ephoto, const char *path, const char *label, Eina_File_Type type) @@ -1085,6 +1081,7 @@ ephoto_entry_new(Ephoto *ephoto, const char *path, const char *label, entry->path = eina_stringshare_add(path); entry->basename = ecore_file_file_get(entry->path); entry->label = eina_stringshare_add(label); + entry->sort_id = NULL; if (type == EINA_FILE_DIR) entry->is_dir = EINA_TRUE; else if (type == EINA_FILE_LNK && ecore_file_is_dir( @@ -1136,6 +1133,8 @@ ephoto_entry_free(Ephoto *ephoto, Ephoto_Entry *entry) ephoto->selentries = eina_list_remove_list(ephoto->selentries, node); } + if (entry->sort_id) + eina_stringshare_del(entry->sort_id); } eina_stringshare_del(entry->path); eina_stringshare_del(entry->label); diff --git a/src/bin/ephoto_thumb_browser.c b/src/bin/ephoto_thumb_browser.c index 4894870..14eab94 100644 --- a/src/bin/ephoto_thumb_browser.c +++ b/src/bin/ephoto_thumb_browser.c @@ -29,6 +29,8 @@ struct _Ephoto_Thumb_Browser Evas_Object *nolabel; Evas_Object *search; Evas_Object *menu; + Evas_Object *hover; + Elm_Object_Item *similarity; Elm_Object_Item *last_sel; Ephoto_Sort sort; Eio_File *ls; @@ -284,7 +286,7 @@ _thumb_file_icon_get(void *data, Evas_Object *obj, if (e) { - thumb = ephoto_thumb_add(e->ephoto, obj, e->path); + thumb = ephoto_thumb_add(e->ephoto, obj, e); evas_object_show(thumb); } return thumb; @@ -293,7 +295,7 @@ _thumb_file_icon_get(void *data, Evas_Object *obj, static void _thumb_item_del(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED) { - /* The entry is already freed when changing directories. */ + /*The entry is already freed when changing directories*/ } static int @@ -373,6 +375,20 @@ _entry_cmp_grid_mod_desc(const void *pa, const void *pb) } } +static int +_entry_cmp_grid_similarity(const void *pa, const void *pb) +{ + const Ephoto_Entry *a, *b; + + a = elm_object_item_data_get(pa); + b = elm_object_item_data_get(pb); + + if (!a->sort_id || !b->sort_id) + return 0; + else + return strcmp(a->sort_id, b->sort_id); +} + static void _sort_alpha_asc(void *data, Evas_Object *obj, void *event_data EINA_UNUSED) @@ -445,6 +461,110 @@ _sort_mod_desc(void *data, Evas_Object *obj EINA_UNUSED, NULL, tb->dirs_only, tb->thumbs_only); } +static Eina_Bool +_similarity_items_process(void *data) +{ + Ephoto_Thumb_Browser *tb = data; + Ephoto_Entry *entry; + int i = 0; + + if ((tb->animator.processed == tb->animator.count)) + { + Evas_Object *popup = evas_object_data_get(tb->grid, "popup"); + + if (tb->animator.count == 0) + return EINA_TRUE; + tb->animator.todo_items = NULL; + tb->processing = 0; + if (popup) + { + evas_object_del(popup); + evas_object_data_del(popup, "popup"); + } + return EINA_FALSE; + } + tb->animator.todo_items = NULL; + tb->processing = 1; + EINA_LIST_FREE(tb->todo_items, entry) + { + i++; + if (i > TODO_ITEM_MIN_BATCH) + return EINA_TRUE; + const Elm_Gengrid_Item_Class *ic; + + ic = &_ephoto_thumb_file_class; + if (tb->sort == EPHOTO_SORT_SIMILARITY) + entry->item = + elm_gengrid_item_sorted_insert(tb->grid, ic, entry, + _entry_cmp_grid_similarity, NULL, NULL); + if (entry->item) + { + elm_object_item_data_set(entry->item, entry); + } + else + { + ephoto_entry_free(tb->ephoto, entry); + } + tb->animator.processed++; + } + return EINA_TRUE; +} + +static void +_sort_similarity(void *data, Evas_Object *obj EINA_UNUSED, + void *event_data EINA_UNUSED) +{ + Ephoto_Thumb_Browser *tb = data; + Evas_Object *popup, *box, *label, *pb, *ic; + + tb->sort = EPHOTO_SORT_SIMILARITY; + tb->thumbs_only = 1; + tb->dirs_only = 0; + ic = elm_icon_add(obj); + + elm_icon_standard_set(ic, "view-sort-ascending"); + elm_object_part_content_set(obj, "icon", ic); + evas_object_show(ic); + + ephoto_thumb_browser_clear(tb->ephoto); + + tb->todo_items = eina_list_clone(tb->entries); + tb->animator.count = eina_list_count(tb->todo_items); + tb->animator.processed = 0; + if (!tb->animator.todo_items) + tb->animator.todo_items = ecore_animator_add(_similarity_items_process, tb); + + popup = elm_popup_add(tb->ephoto->win); + elm_object_part_text_set(popup, "title,text", _("Sorting")); + elm_popup_orient_set(popup, ELM_POPUP_ORIENT_CENTER); + + box = elm_box_add(popup); + elm_box_horizontal_set(box, EINA_FALSE); + evas_object_size_hint_weight_set(box, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_size_hint_align_set(box, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_show(box); + + label = elm_label_add(box); + elm_object_text_set(label, _("Sorting Images By Similarity")); + evas_object_size_hint_weight_set(label, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(label, EVAS_HINT_FILL, EVAS_HINT_FILL); + elm_box_pack_end(box, label); + evas_object_show(label); + + pb = elm_progressbar_add(box); + evas_object_size_hint_weight_set(pb, EVAS_HINT_EXPAND, 0.0); + evas_object_size_hint_align_set(pb, EVAS_HINT_FILL, 0.5); + elm_object_style_set(pb, "wheel"); + elm_progressbar_pulse_set(pb, EINA_TRUE); + elm_box_pack_end(box, pb); + evas_object_show(pb); + elm_progressbar_pulse(pb, EINA_TRUE); + + evas_object_data_set(tb->grid, "popup", popup); + elm_object_part_content_set(popup, "default", box); + evas_object_show(popup); +} + static void _zoom_in(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) @@ -1027,9 +1147,7 @@ _ephoto_thumb_search_go(void *data, Evas_Object *obj EINA_UNUSED, elm_box_unpack(tb->gridbox, tb->original_grid); evas_object_hide(tb->original_grid); - elm_theme_extension_add(NULL, PACKAGE_DATA_DIR "/themes/ephoto.edj"); tb->grid = elm_gengrid_add(tb->gridbox); - elm_object_style_set(tb->grid, "noclip"); evas_object_size_hint_weight_set(tb->grid, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(tb->grid, EVAS_HINT_FILL, EVAS_HINT_FILL); @@ -1082,7 +1200,7 @@ _ephoto_thumb_search_go(void *data, Evas_Object *obj EINA_UNUSED, e->item = elm_gengrid_item_sorted_insert(tb->grid, ic, e, _entry_cmp_grid_mod_desc, NULL, NULL); - if (e->item) + if (e->item) { Eina_File *f; elm_object_item_data_set(e->item, e); @@ -1234,9 +1352,7 @@ _ephoto_thumb_view_add(Ephoto_Thumb_Browser *tb) EVAS_HINT_FILL); evas_object_show(tb->gridbox); - elm_theme_extension_add(NULL, PACKAGE_DATA_DIR "/themes/ephoto.edj"); tb->grid = elm_gengrid_add(tb->gridbox); - elm_object_style_set(tb->grid, "noclip"); evas_object_size_hint_weight_set(tb->grid, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(tb->grid, EVAS_HINT_FILL, EVAS_HINT_FILL); @@ -1283,11 +1399,11 @@ _todo_items_process(void *data) return EINA_TRUE; tb->animator.todo_items = NULL; tb->processing = 0; + elm_object_item_disabled_set(tb->similarity, EINA_FALSE); return EINA_FALSE; } if ((tb->ls) && (eina_list_count(tb->todo_items) < TODO_ITEM_MIN_BATCH)) return EINA_TRUE; - tb->animator.todo_items = NULL; tb->processing = 1; EINA_LIST_FREE(tb->todo_items, entry) @@ -1339,6 +1455,21 @@ _ephoto_thumb_populate_start(void *data, int type EINA_UNUSED, if (tb->dirs_only) return ECORE_CALLBACK_PASS_ON; + if (tb->sort == EPHOTO_SORT_SIMILARITY) + { + Evas_Object *ic; + + tb->sort = EPHOTO_SORT_ALPHABETICAL_ASCENDING; + + ic = elm_icon_add(tb->hover); + elm_icon_standard_set(ic, "view-sort-ascending"); + elm_object_part_content_set(tb->hover, "icon", ic); + evas_object_show(ic); + + elm_object_text_set(tb->hover, _("Sort")); + } + + elm_object_item_disabled_set(tb->similarity, EINA_TRUE); tb->animator.processed = 0; tb->animator.count = 0; if (tb->ephoto->selentries) @@ -1937,6 +2068,8 @@ ephoto_thumb_browser_show_controls(Ephoto *ephoto) "view-sort-ascending", ELM_ICON_STANDARD, _sort_mod_asc, tb); elm_hoversel_item_add(hover, _("Modification Time Descending"), "view-sort-descending", ELM_ICON_STANDARD, _sort_mod_desc, tb); + tb->similarity = elm_hoversel_item_add(hover, _("Image Simalarity"), + "view-sort-ascending", ELM_ICON_STANDARD, _sort_similarity, tb); elm_object_text_set(hover, _("Sort")); ic = elm_icon_add(hover); evas_object_size_hint_min_set(ic, 20*elm_config_scale_get(), @@ -1950,6 +2083,8 @@ ephoto_thumb_browser_show_controls(Ephoto *ephoto) evas_object_smart_callback_add(hover, "dismissed", _hover_dismissed_cb, tb); elm_box_pack_end(ephoto->controls_right, hover); evas_object_show(hover); + tb->hover = hover; + elm_object_item_disabled_set(tb->similarity, EINA_TRUE); } Evas_Object *