forked from enlightenment/ephoto
Move the entry list building to the main file, since it is used by both the thumb and flow views.
Inform the relevant parties when the list starts and stops getting populated, and when an entry is created, via ecore events. Remove the pending path stuff from the thumb browser, as it is not for it. Remove the ability to set the currently viewed file by path alone, always rely on an entry. Correctly set the disable states on the navigation toolbar buttons when starting ephoto directly in flow mode SVN revision: 54541
This commit is contained in:
parent
7a0f157742
commit
a9a783385d
|
@ -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");
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue