diff --git a/src/bin/ephoto.c b/src/bin/ephoto.c index 8b98ec4..b0b5cdc 100644 --- a/src/bin/ephoto.c +++ b/src/bin/ephoto.c @@ -44,7 +44,7 @@ elm_main(int argc, char **argv) ethumb_client_crop_align_set(client, 0.5, 0.5); ethumb_client_aspect_set(client, ETHUMB_THUMB_CROP); ethumb_client_orientation_set(client, ETHUMB_THUMB_ORIENT_ORIGINAL); - __log_domain = eina_log_domain_register("ephoto", EINA_COLOR_BLUE); + __log_domain = eina_log_domain_register("ephoto", EINA_COLOR_ORANGE); if (!__log_domain) { EINA_LOG_ERR("Could not register log domain: Ephoto"); diff --git a/src/bin/ephoto.h b/src/bin/ephoto.h index 4a217bf..7503714 100644 --- a/src/bin/ephoto.h +++ b/src/bin/ephoto.h @@ -27,6 +27,7 @@ typedef struct _Ephoto_Config Ephoto_Config; typedef struct _Ephoto Ephoto; typedef struct _Ephoto_Entry Ephoto_Entry; +typedef struct _Ephoto_Event_Entry_Create Ephoto_Event_Entry_Create; typedef enum _Ephoto_State Ephoto_State; typedef enum _Ephoto_Orient Ephoto_Orient; @@ -36,6 +37,7 @@ 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 *o, const char *path); +void ephoto_directory_set(Ephoto *ephoto, const char *path); Ephoto_Orient ephoto_file_orient_get(const char *path); @@ -44,8 +46,8 @@ void ephoto_config_save(Ephoto *em, Eina_Bool instant); void ephoto_config_free(Ephoto *em); Evas_Object *ephoto_flow_browser_add(Ephoto *ephoto, Evas_Object *parent); -void ephoto_flow_browser_path_set(Evas_Object *obj, const char *image); void ephoto_flow_browser_entry_set(Evas_Object *obj, Ephoto_Entry *entry); +void ephoto_flow_browser_path_pending_set(Evas_Object *obj, const char *path); /* smart callbacks called: * "back" - the user want to go back to the previous screen. */ @@ -59,8 +61,6 @@ void ephoto_slideshow_entry_set(Evas_Object *obj, Ephoto_Entry *entry); Evas_Object *ephoto_directory_thumb_add(Evas_Object *parent, Ephoto_Entry *e); Evas_Object *ephoto_thumb_browser_add(Ephoto *ephoto, Evas_Object *parent); -void ephoto_thumb_browser_directory_set(Evas_Object *obj, const char *path); -void ephoto_thumb_browser_path_pending_set(Evas_Object *obj, const char *path, void (*cb)(void *data, Ephoto_Entry *entry), const void *data); /* smart callbacks called: * "selected" - an item in the thumb browser is selected. The selected Ephoto_Entry is passed as event_info argument. @@ -123,6 +123,11 @@ struct _Ephoto struct { Ecore_Timer *thumb_regen; } timer; + struct { + Ecore_Job *change_dir; + } job; + + Eio_File *ls; Evas_Object *prefs_win; Ephoto_State state, prev_state; @@ -144,6 +149,11 @@ struct _Ephoto_Entry Eina_Bool is_up : 1; }; +struct _Ephoto_Event_Entry_Create +{ + Ephoto_Entry *entry; +}; + Ephoto_Entry *ephoto_entry_new(Ephoto *ephoto, const char *path, const char *label); void ephoto_entry_free(Ephoto_Entry *entry); void ephoto_entry_free_listener_add(Ephoto_Entry *entry, void (*cb)(void *data, const Ephoto_Entry *entry), const void *data); @@ -182,4 +192,9 @@ _ephoto_eina_file_direct_info_image_useful(const Eina_File_Direct_Info *info) //return strncmp(type, "image/", sizeof("image/") - 1) == 0; } +extern int EPHOTO_EVENT_ENTRY_CREATE; +extern int EPHOTO_EVENT_POPULATE_START; +extern int EPHOTO_EVENT_POPULATE_END; +extern int EPHOTO_EVENT_POPULATE_ERROR; + #endif diff --git a/src/bin/ephoto_flow_browser.c b/src/bin/ephoto_flow_browser.c index 0d8eab2..3160468 100644 --- a/src/bin/ephoto_flow_browser.c +++ b/src/bin/ephoto_flow_browser.c @@ -41,9 +41,10 @@ struct _Ephoto_Flow_Browser #endif Elm_Toolbar_Item *slideshow; } action; - const char *path; + const char *pending_path; Ephoto_Entry *entry; Ephoto_Orient orient; + Eina_List *handlers; }; struct _Ephoto_Viewer @@ -512,10 +513,10 @@ _ephoto_flow_browser_recalc(Ephoto_Flow_Browser *fb) fb->viewer = NULL; } - if (fb->path) + if (fb->entry) { - const char *bname = ecore_file_file_get(fb->path); - fb->viewer = _viewer_add(fb->orient_layout, fb->path); + const char *bname = ecore_file_file_get(fb->entry->path); + fb->viewer = _viewer_add(fb->orient_layout, fb->entry->path); elm_layout_content_set (fb->orient_layout, "elm.swallow.content", fb->viewer); evas_object_show(fb->viewer); @@ -523,7 +524,7 @@ _ephoto_flow_browser_recalc(Ephoto_Flow_Browser *fb) (fb->viewer, EVAS_CALLBACK_MOUSE_WHEEL, _mouse_wheel, fb); edje_object_part_text_set(fb->edje, "elm.text.title", bname); ephoto_title_set(fb->ephoto, bname); - fb->orient = ephoto_file_orient_get(fb->path); + fb->orient = ephoto_file_orient_get(fb->entry->path); _orient_apply(fb); } @@ -794,9 +795,14 @@ static void _layout_del(void *data, Evas *e __UNUSED__, Evas_Object *o __UNUSED__, void *event_info __UNUSED__) { Ephoto_Flow_Browser *fb = data; + Ecore_Event_Handler *handler; + + EINA_LIST_FREE(fb->handlers, handler) + ecore_event_handler_del(handler); if (fb->entry) ephoto_entry_free_listener_del(fb->entry, _entry_free, fb); - eina_stringshare_del(fb->path); + if (fb->pending_path) + eina_stringshare_del(fb->pending_path); free(fb); } @@ -818,6 +824,36 @@ _toolbar_item_separator_add(Ephoto_Flow_Browser *fb) return it; } +static Eina_Bool +_ephoto_flow_populate_end(void *data, int type __UNUSED__, void *event __UNUSED__) +{ + Ephoto_Flow_Browser *fb = data; + + _ephoto_flow_browser_toolbar_eval(fb); + + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_ephoto_flow_entry_create(void *data, int type __UNUSED__, void *event __UNUSED__) +{ + Ephoto_Flow_Browser *fb = data; + Ephoto_Event_Entry_Create *ev = event; + Ephoto_Entry *e; + + e = ev->entry; + if (!fb->entry && fb->pending_path && e->path == fb->pending_path) + { + DBG("Adding entry %p for path %s", e, fb->pending_path); + + eina_stringshare_del(fb->pending_path); + fb->pending_path = NULL; + ephoto_flow_browser_entry_set(fb->ephoto->flow_browser, e); + } + + return ECORE_CALLBACK_PASS_ON; +} + Evas_Object * ephoto_flow_browser_add(Ephoto *ephoto, Evas_Object *parent) { @@ -913,6 +949,14 @@ ephoto_flow_browser_add(Ephoto *ephoto, Evas_Object *parent) _ephoto_flow_browser_toolbar_eval(fb); + fb->handlers = eina_list_append + (fb->handlers, ecore_event_handler_add + (EPHOTO_EVENT_POPULATE_END, _ephoto_flow_populate_end, fb)); + + fb->handlers = eina_list_append + (fb->handlers, ecore_event_handler_add + (EPHOTO_EVENT_ENTRY_CREATE, _ephoto_flow_entry_create, fb)); + return layout; error: @@ -920,42 +964,28 @@ ephoto_flow_browser_add(Ephoto *ephoto, Evas_Object *parent) return NULL; } -void -ephoto_flow_browser_path_set(Evas_Object *obj, const char *path) -{ - Ephoto_Flow_Browser *fb = evas_object_data_get(obj, "flow_browser"); - EINA_SAFETY_ON_NULL_RETURN(fb); - - DBG("path '%s', was '%s'", path ? path : "", fb->path ? fb->path : ""); - if (!eina_stringshare_replace(&fb->path, path)) return; - fb->entry = NULL; - _ephoto_flow_browser_recalc(fb); - _zoom_fit(fb); -} - void ephoto_flow_browser_entry_set(Evas_Object *obj, Ephoto_Entry *entry) { Ephoto_Flow_Browser *fb = evas_object_data_get(obj, "flow_browser"); + Eina_Bool same_file = EINA_FALSE; EINA_SAFETY_ON_NULL_RETURN(fb); DBG("entry %p, was %p", entry, fb->entry); if (fb->entry) - ephoto_entry_free_listener_del(fb->entry, _entry_free, fb); + { + ephoto_entry_free_listener_del(fb->entry, _entry_free, fb); + if (entry && entry->path == fb->entry->path) + same_file = EINA_TRUE; + } fb->entry = entry; if (entry) ephoto_entry_free_listener_add(entry, _entry_free, fb); - - if (!entry) - { - eina_stringshare_replace(&fb->path, NULL); - _ephoto_flow_browser_toolbar_eval(fb); - } - else if (!eina_stringshare_replace(&fb->path, entry->path)) + if (!fb->entry || same_file) _ephoto_flow_browser_toolbar_eval(fb); else { @@ -963,3 +993,13 @@ ephoto_flow_browser_entry_set(Evas_Object *obj, Ephoto_Entry *entry) _zoom_fit(fb); } } + +void +ephoto_flow_browser_path_pending_set(Evas_Object *obj, const char *path) +{ + Ephoto_Flow_Browser *fb = evas_object_data_get(obj, "flow_browser"); + EINA_SAFETY_ON_NULL_RETURN(fb); + + DBG("Setting pending path '%s'", path); + fb->pending_path = eina_stringshare_add(path); +} diff --git a/src/bin/ephoto_main.c b/src/bin/ephoto_main.c index 8bc2896..3c99720 100644 --- a/src/bin/ephoto_main.c +++ b/src/bin/ephoto_main.c @@ -1,5 +1,10 @@ #include "ephoto.h" +int EPHOTO_EVENT_ENTRY_CREATE = 0; +int EPHOTO_EVENT_POPULATE_START = 0; +int EPHOTO_EVENT_POPULATE_END = 0; +int EPHOTO_EVENT_POPULATE_ERROR = 0; + typedef struct _Ephoto_Entry_Free_Listener Ephoto_Entry_Free_Listener; struct _Ephoto_Entry_Free_Listener { @@ -19,7 +24,7 @@ _ephoto_thumb_browser_show(Ephoto *ephoto, Ephoto_Entry *entry) { DBG("entry '%s'", entry ? entry->path : ""); - ephoto_flow_browser_path_set(ephoto->flow_browser, NULL); + ephoto_flow_browser_entry_set(ephoto->flow_browser, NULL); ephoto_slideshow_entry_set(ephoto->slideshow, NULL); elm_pager_content_promote(ephoto->pager, ephoto->thumb_browser); _ephoto_state_set(ephoto, EPHOTO_STATE_THUMB); @@ -104,18 +109,6 @@ _ephoto_flow_browser_slideshow(void *data, Evas_Object *obj __UNUSED__, void *ev _ephoto_slideshow_show(ephoto, entry); } -static void -_pending_path_found(void *data, Ephoto_Entry *entry) -{ - Ephoto *ephoto = data; - if (!entry) - { - ERR("not found entry, but it should be in directory? weird!"); - return; - } - ephoto_flow_browser_entry_set(ephoto->flow_browser, entry); -} - static void _win_free(void *data, Evas *e __UNUSED__, Evas_Object *o __UNUSED__, void *event_info __UNUSED__) { @@ -132,6 +125,11 @@ ephoto_window_add(const char *path) char buf[PATH_MAX]; EINA_SAFETY_ON_NULL_RETURN_VAL(ephoto, NULL); + EPHOTO_EVENT_ENTRY_CREATE = ecore_event_type_new(); + EPHOTO_EVENT_POPULATE_START = ecore_event_type_new(); + EPHOTO_EVENT_POPULATE_END = ecore_event_type_new(); + EPHOTO_EVENT_POPULATE_ERROR = ecore_event_type_new(); + ephoto->win = elm_win_add(NULL, "ephoto", ELM_WIN_BASIC); if (!ephoto->win) { @@ -231,17 +229,15 @@ ephoto_window_add(const char *path) if (ecore_file_is_dir(path)) { - ephoto_thumb_browser_directory_set(ephoto->thumb_browser, path); + ephoto_directory_set(ephoto, path); _ephoto_thumb_browser_show(ephoto, NULL); } else { char *dir = ecore_file_dir_get(path); - ephoto_thumb_browser_directory_set(ephoto->thumb_browser, dir); + ephoto_directory_set(ephoto, dir); free(dir); - ephoto_thumb_browser_path_pending_set - (ephoto->thumb_browser, path, _pending_path_found, ephoto); - ephoto_flow_browser_path_set(ephoto->flow_browser, path); + ephoto_flow_browser_path_pending_set(ephoto->flow_browser, path); elm_pager_content_promote(ephoto->pager, ephoto->flow_browser); ephoto->state = EPHOTO_STATE_FLOW; @@ -263,6 +259,120 @@ ephoto_title_set(Ephoto *ephoto, const char *title) elm_win_title_set(ephoto->win, buf); } +static int +_entry_cmp(const void *pa, const void *pb) +{ + const Ephoto_Entry *a = pa, *b = pb; + if (a->is_dir == b->is_dir) + return strcoll(a->basename, b->basename); + else if (a->is_dir) + return -1; + else + return 1; +} + +static void +_ephoto_populate_main(void *data, Eio_File *handler __UNUSED__, const Eina_File_Direct_Info *info) +{ + Ephoto *ephoto = data; + Ephoto_Entry *e; + Ephoto_Event_Entry_Create *ev; + + e = ephoto_entry_new(ephoto, info->path, info->path + info->name_start); + if (info->type == EINA_FILE_DIR) e->is_dir = EINA_TRUE; + else if (info->type == EINA_FILE_REG) e->is_dir = EINA_FALSE; + else e->is_dir = !_ephoto_eina_file_direct_info_image_useful(info); + + if (!ephoto->entries) + ephoto->entries = eina_list_append(ephoto->entries, e); + else + { + int near_cmp; + Eina_List *near_node = eina_list_search_sorted_near_list + (ephoto->entries, _entry_cmp, e, &near_cmp); + + if (near_cmp < 0) + ephoto->entries = eina_list_append_relative_list + (ephoto->entries, e, near_node); + else + ephoto->entries = eina_list_prepend_relative_list + (ephoto->entries, e, near_node); + } + + ev = calloc(1, sizeof(Ephoto_Event_Entry_Create)); + ev->entry = e; + + ecore_event_add(EPHOTO_EVENT_ENTRY_CREATE, ev, NULL, NULL); +} + +static Eina_Bool +_ephoto_populate_filter(void *data __UNUSED__, Eio_File *handler __UNUSED__, const Eina_File_Direct_Info *info) +{ + const char *bname = info->path + info->name_start; + + if (bname[0] == '.') return EINA_FALSE; + if (info->type == EINA_FILE_DIR) return EINA_TRUE; + + return _ephoto_eina_file_direct_info_image_useful(info); +} + +static void +_ephoto_populate_end(void *data, Eio_File *handler __UNUSED__) +{ + Ephoto *ephoto = data; + ephoto->ls = NULL; + + ecore_event_add(EPHOTO_EVENT_POPULATE_END, NULL, NULL, NULL); +} + +static void +_ephoto_populate_error(void *data, Eio_File *handler, int error) +{ + Ephoto *ephoto = data; + if (error) ERR("could not populate: %s", strerror(error)); + + /* XXX: Perhaps it would be better to _not_ emit POPULATE_END here */ + ecore_event_add(EPHOTO_EVENT_POPULATE_ERROR, NULL, NULL, NULL); + _ephoto_populate_end(ephoto, handler); +} + +static void +_ephoto_populate_entries(Ephoto *ephoto) +{ + /* Edje_External_Param param; */ + DBG("populate from '%s'", ephoto->config->directory); + + ephoto_entries_free(ephoto); + + ephoto->ls = eio_file_stat_ls(ephoto->config->directory, + _ephoto_populate_filter, + _ephoto_populate_main, + _ephoto_populate_end, + _ephoto_populate_error, + ephoto); + + ecore_event_add(EPHOTO_EVENT_POPULATE_START, NULL, NULL, NULL); +} + +static void +_ephoto_change_dir(void *data) +{ + Ephoto *ephoto = data; + ephoto->job.change_dir = NULL; + _ephoto_populate_entries(ephoto); +} + +void +ephoto_directory_set(Ephoto *ephoto, const char *path) +{ + EINA_SAFETY_ON_NULL_RETURN(ephoto); + + ephoto_title_set(ephoto, path); + eina_stringshare_replace(&ephoto->config->directory, path); + if (ephoto->job.change_dir) ecore_job_del(ephoto->job.change_dir); + ephoto->job.change_dir = ecore_job_add(_ephoto_change_dir, ephoto); +} + static Eina_Bool _thumb_gen_size_changed_timer_cb(void *data) { diff --git a/src/bin/ephoto_thumb_browser.c b/src/bin/ephoto_thumb_browser.c index 78e0a86..1ea3003 100644 --- a/src/bin/ephoto_thumb_browser.c +++ b/src/bin/ephoto_thumb_browser.c @@ -20,20 +20,14 @@ struct _Ephoto_Thumb_Browser Evas_Object *toolbar; Eio_File *ls; Eina_List *todo_items; + Eina_List *grid_items; + Eina_List *handlers; struct { Elm_Toolbar_Item *zoom_in; Elm_Toolbar_Item *zoom_out; Elm_Toolbar_Item *view_flow; Elm_Toolbar_Item *slideshow; } action; - struct { - const char *path; - void (*cb)(void *data, Ephoto_Entry *entry); - const void *data; - } pending; - struct { - Ecore_Job *change_dir; - } job; struct { Ecore_Animator *todo_items; } animator; @@ -47,6 +41,13 @@ _todo_items_free(Ephoto_Thumb_Browser *tb) tb->todo_items = NULL; } +static void +_grid_items_free(Ephoto_Thumb_Browser *tb) +{ + eina_list_free(tb->grid_items); + tb->grid_items = NULL; +} + static Ephoto_Entry * _first_file_entry_find(Ephoto_Thumb_Browser *tb) { @@ -115,10 +116,14 @@ _ephoto_thumb_file_icon_get(void *data, Evas_Object *obj, const char *part __UNU } static void -_ephoto_thumb_item_del(void *data, Evas_Object *obj __UNUSED__) +_ephoto_thumb_item_del(void *data __UNUSED__, Evas_Object *obj __UNUSED__) { + /* FIXME: the entry is already freed when changing directories + * One solution is to take care of this cleaning when manually removing + * some grid items Ephoto_Entry *e = data; e->item = NULL; + */ } static const Elm_Gengrid_Item_Class _ephoto_thumb_dir_class = { @@ -154,7 +159,11 @@ static const Elm_Gengrid_Item_Class _ephoto_thumb_file_class = { static int _entry_cmp(const void *pa, const void *pb) { - const Ephoto_Entry *a = pa, *b = pb; + const Elm_Gengrid_Item *ia = pa; + const Ephoto_Entry *a, *b = pb; + + a = elm_gengrid_item_data_get(ia); + if (a->is_dir == b->is_dir) return strcoll(a->basename, b->basename); else if (a->is_dir) @@ -167,57 +176,50 @@ static void _entry_item_add(Ephoto_Thumb_Browser *tb, Ephoto_Entry *e) { const Elm_Gengrid_Item_Class *ic; + int near_cmp; + Elm_Gengrid_Item *near_item = NULL; + Eina_List *near_node = NULL; + + near_node = eina_list_search_sorted_near_list + (tb->grid_items, _entry_cmp, e, &near_cmp); - DBG("populate add '%s'", e->path); + if (near_node) + near_item = near_node->data; if (e->is_dir) ic = &_ephoto_thumb_dir_class; else ic = &_ephoto_thumb_file_class; - if (!tb->ephoto->entries) + if (!near_item) { e->item = elm_gengrid_item_append(tb->grid, ic, e, NULL, NULL); - tb->ephoto->entries = eina_list_append(tb->ephoto->entries, e); + tb->grid_items = eina_list_append(tb->grid_items, e->item); } else { - int near_cmp; - Ephoto_Entry *near_entry; - Elm_Gengrid_Item *near_item; - Eina_List *near_node = eina_list_search_sorted_near_list - (tb->ephoto->entries, _entry_cmp, e, &near_cmp); - - near_entry = near_node->data; - near_item = near_entry->item; if (near_cmp < 0) { e->item = elm_gengrid_item_insert_after - (tb->grid, ic, e, near_item, NULL, NULL); - tb->ephoto->entries = eina_list_append_relative_list - (tb->ephoto->entries, e, near_node); + (tb->grid, ic, e, near_item, NULL, NULL); + tb->grid_items = eina_list_append_relative + (tb->grid_items, e->item, near_item); } else { e->item = elm_gengrid_item_insert_before - (tb->grid, ic, e, near_item, NULL, NULL); - tb->ephoto->entries = eina_list_prepend_relative_list - (tb->ephoto->entries, e, near_node); + (tb->grid, ic, e, near_item, NULL, NULL); + tb->grid_items = eina_list_prepend_relative + (tb->grid_items, e->item, near_item); } } - if (!e->item) + if (e->item) + elm_gengrid_item_data_set(e->item, e); + else { ERR("could not add item to grid: path '%s'", e->path); ephoto_entry_free(e); return; } - - if (tb->pending.path == e->path) - { - tb->pending.cb((void*)tb->pending.data, e); - tb->pending.cb = NULL; - tb->pending.data = NULL; - eina_stringshare_replace(&tb->pending.path, NULL); - } } static void @@ -266,98 +268,6 @@ _todo_items_process(void *data) return EINA_FALSE; } -static void -_ephoto_populate_main(void *data, Eio_File *handler __UNUSED__, const Eina_File_Direct_Info *info) -{ - Ephoto_Thumb_Browser *tb = data; - Ephoto_Entry *e; - - e = ephoto_entry_new(tb->ephoto, info->path, info->path + info->name_start); - if (info->type == EINA_FILE_DIR) e->is_dir = EINA_TRUE; - else if (info->type == EINA_FILE_REG) e->is_dir = EINA_FALSE; - else e->is_dir = !_ephoto_eina_file_direct_info_image_useful(info); - - tb->todo_items = eina_list_append(tb->todo_items, e); - - if (!tb->animator.todo_items) - tb->animator.todo_items = ecore_animator_add(_todo_items_process, tb); -} - -static Eina_Bool -_ephoto_populate_filter(void *data __UNUSED__, Eio_File *handler __UNUSED__, const Eina_File_Direct_Info *info) -{ - const char *bname = info->path + info->name_start; - - if (bname[0] == '.') return EINA_FALSE; - if (info->type == EINA_FILE_DIR) return EINA_TRUE; - - return _ephoto_eina_file_direct_info_image_useful(info); -} - -static void -_ephoto_populate_end(void *data, Eio_File *handler __UNUSED__) -{ - Ephoto_Thumb_Browser *tb = data; - tb->ls = NULL; - - if (tb->layout_deleted) - { - free(tb); - return; - } - - if (!tb->animator.todo_items) _up_item_add_if_required(tb); - - if (tb->pending.cb) - { - tb->pending.cb((void*)tb->pending.data, NULL); - tb->pending.cb = NULL; - } - tb->pending.data = NULL; - eina_stringshare_replace(&tb->pending.path, NULL); - edje_object_signal_emit(tb->edje, "populate,stop", "ephoto"); -} - -static void -_ephoto_populate_error(void *data, Eio_File *handler, int error) -{ - Ephoto_Thumb_Browser *tb = data; - if (error) ERR("could not populate: %s", strerror(error)); - edje_object_signal_emit(tb->edje, "populate,error", "ephoto"); - _ephoto_populate_end(tb, handler); -} - -static void -_ephoto_populate_entries(Ephoto_Thumb_Browser *tb) -{ - /* Edje_External_Param param; */ - DBG("populate from '%s'", tb->ephoto->config->directory); - - evas_object_smart_callback_call(tb->layout, "changed,directory", NULL); - - _todo_items_free(tb); - elm_gengrid_clear(tb->grid); - ephoto_entries_free(tb->ephoto); - - elm_fileselector_entry_path_set(tb->fsel, tb->ephoto->config->directory); - - edje_object_signal_emit(tb->edje, "populate,start", "ephoto"); - tb->ls = eio_file_stat_ls(tb->ephoto->config->directory, - _ephoto_populate_filter, - _ephoto_populate_main, - _ephoto_populate_end, - _ephoto_populate_error, - tb); -} - -static void -_ephoto_thumb_change_dir(void *data) -{ - Ephoto_Thumb_Browser *tb = data; - tb->job.change_dir = NULL; - _ephoto_populate_entries(tb); -} - static void _ephoto_thumb_selected(void *data, Evas_Object *o __UNUSED__, void *event_info) { @@ -368,7 +278,7 @@ _ephoto_thumb_selected(void *data, Evas_Object *o __UNUSED__, void *event_info) elm_gengrid_item_selected_set(it, EINA_FALSE); if (e->is_dir) - ephoto_thumb_browser_directory_set(tb->layout, e->path); + ephoto_directory_set(tb->ephoto, e->path); else evas_object_smart_callback_call(tb->layout, "view", e); } @@ -379,7 +289,7 @@ _changed_dir(void *data, Evas_Object *o __UNUSED__, void *event_info) Ephoto_Thumb_Browser *tb = data; const char *path = event_info; if (!path) return; - ephoto_thumb_browser_directory_set(tb->layout, path); + ephoto_directory_set(tb->ephoto, path); } static void @@ -388,7 +298,7 @@ _changed_dir_text(void *data, Evas_Object *o __UNUSED__, void *event_info __UNUS Ephoto_Thumb_Browser *tb = data; const char *path = elm_fileselector_entry_path_get(tb->fsel); if (ecore_file_is_dir(path)) - ephoto_thumb_browser_directory_set(tb->layout, path); + ephoto_directory_set(tb->ephoto, path); } static void @@ -434,7 +344,7 @@ _view_flow(void *data, Evas_Object *o __UNUSED__, void *event_info __UNUSED__) if (!entry) return; if (entry->is_dir) - ephoto_thumb_browser_directory_set(tb->layout, entry->path); + ephoto_directory_set(tb->ephoto, entry->path); else evas_object_smart_callback_call(tb->layout, "view", entry); } @@ -472,7 +382,7 @@ _key_down(void *data, Evas *e __UNUSED__, Evas_Object *o __UNUSED__, void *event char *parent = ecore_file_dir_get (tb->ephoto->config->directory); if (parent) - ephoto_thumb_browser_directory_set(tb->layout, parent); + ephoto_directory_set(tb->ephoto, parent); free(parent); } } @@ -497,21 +407,13 @@ static void _layout_del(void *data, Evas *e __UNUSED__, Evas_Object *o __UNUSED__, void *event_info __UNUSED__) { Ephoto_Thumb_Browser *tb = data; + Ecore_Event_Handler *handler; _todo_items_free(tb); + _grid_items_free(tb); + EINA_LIST_FREE(tb->handlers, handler) + ecore_event_handler_del(handler); - if (tb->pending.cb) - { - tb->pending.cb((void*)tb->pending.data, NULL); - tb->pending.cb = NULL; - tb->pending.data = NULL; - } - eina_stringshare_replace(&tb->pending.path, NULL); - if (tb->job.change_dir) - { - ecore_job_del(tb->job.change_dir); - tb->job.change_dir = NULL; - } if (tb->animator.todo_items) { ecore_animator_del(tb->animator.todo_items); @@ -535,6 +437,68 @@ _toolbar_item_add(Ephoto_Thumb_Browser *tb, const char *icon, const char *label, return item; } +static Eina_Bool +_ephoto_thumb_populate_start(void *data, int type __UNUSED__, void *event __UNUSED__) +{ + Ephoto_Thumb_Browser *tb = data; + + evas_object_smart_callback_call(tb->layout, "changed,directory", NULL); + + _todo_items_free(tb); + _grid_items_free(tb); + elm_gengrid_clear(tb->grid); + elm_fileselector_entry_path_set(tb->fsel, tb->ephoto->config->directory); + + edje_object_signal_emit(tb->edje, "populate,start", "ephoto"); + + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_ephoto_thumb_populate_end(void *data, int type __UNUSED__, void *event __UNUSED__) +{ + Ephoto_Thumb_Browser *tb = data; + + tb->ls = NULL; + if (tb->layout_deleted) + { + free(tb); + return ECORE_CALLBACK_PASS_ON; + } + + if (!tb->animator.todo_items) _up_item_add_if_required(tb); + + edje_object_signal_emit(tb->edje, "populate,stop", "ephoto"); + + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_ephoto_thumb_populate_error(void *data, int type __UNUSED__, void *event __UNUSED__) +{ + Ephoto_Thumb_Browser *tb = data; + + edje_object_signal_emit(tb->edje, "populate,error", "ephoto"); + + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_ephoto_thumb_entry_create(void *data, int type __UNUSED__, void *event) +{ + Ephoto_Thumb_Browser *tb = data; + Ephoto_Event_Entry_Create *ev = event; + Ephoto_Entry *e; + + e = ev->entry; + tb->todo_items = eina_list_append(tb->todo_items, e); + + if (!tb->animator.todo_items) + tb->animator.todo_items = ecore_animator_add(_todo_items_process, tb); + + return ECORE_CALLBACK_PASS_ON; +} + Evas_Object * ephoto_thumb_browser_add(Ephoto *ephoto, Evas_Object *parent) { @@ -616,36 +580,25 @@ ephoto_thumb_browser_add(Ephoto *ephoto, Evas_Object *parent) evas_object_show(tb->grid); elm_layout_box_append(tb->layout, "elm.box.content", tb->grid); + tb->handlers = eina_list_append + (tb->handlers, ecore_event_handler_add + (EPHOTO_EVENT_POPULATE_START, _ephoto_thumb_populate_start, tb)); + + tb->handlers = eina_list_append + (tb->handlers, ecore_event_handler_add + (EPHOTO_EVENT_POPULATE_END, _ephoto_thumb_populate_end, tb)); + + tb->handlers = eina_list_append + (tb->handlers, ecore_event_handler_add + (EPHOTO_EVENT_POPULATE_ERROR, _ephoto_thumb_populate_error, tb)); + + tb->handlers = eina_list_append + (tb->handlers, ecore_event_handler_add + (EPHOTO_EVENT_ENTRY_CREATE, _ephoto_thumb_entry_create, tb)); + return layout; error: evas_object_del(layout); return NULL; } - -void -ephoto_thumb_browser_directory_set(Evas_Object *obj, const char *path) -{ - Ephoto_Thumb_Browser *tb = evas_object_data_get(obj, "thumb_browser"); - EINA_SAFETY_ON_NULL_RETURN(tb); - - eina_stringshare_replace(&tb->pending.path, NULL); - tb->pending.cb = NULL; - tb->pending.data = NULL; - - ephoto_title_set(tb->ephoto, path); - - eina_stringshare_replace(&tb->ephoto->config->directory, path); - if (tb->job.change_dir) ecore_job_del(tb->job.change_dir); - tb->job.change_dir = ecore_job_add(_ephoto_thumb_change_dir, tb); -} - -void -ephoto_thumb_browser_path_pending_set(Evas_Object *obj, const char *path, void (*cb)(void *data, Ephoto_Entry *entry), const void *data) -{ - Ephoto_Thumb_Browser *tb = evas_object_data_get(obj, "thumb_browser"); - EINA_SAFETY_ON_NULL_RETURN(tb); - eina_stringshare_replace(&tb->pending.path, path); - tb->pending.cb = cb; - tb->pending.data = data; -}