From 6c4b19d5d034f66aacbdda246b5b0363bc8d374d Mon Sep 17 00:00:00 2001 From: Carsten Haitzler Date: Sat, 15 Jul 2006 16:29:14 +0000 Subject: [PATCH] workign on efm2... kind of workign at the basics now... SVN revision: 23949 --- src/bin/e_fm.c | 729 +++++++++++++++++++++++++++++++++++++++++++++-- src/bin/e_fm.h | 12 +- src/bin/e_test.c | 14 +- src/bin/e_user.c | 7 + 4 files changed, 730 insertions(+), 32 deletions(-) diff --git a/src/bin/e_fm.c b/src/bin/e_fm.c index 2e982bb58..8d01d63c9 100644 --- a/src/bin/e_fm.c +++ b/src/bin/e_fm.c @@ -16,6 +16,7 @@ struct _E_Fm2_Smart_Data Evas_Object *clip; char *dev; char *path; + char *realpath; E_Fm2_View_Mode view_mode; struct { Evas_Coord w, h; @@ -28,7 +29,13 @@ struct _E_Fm2_Smart_Data int member_max; } regions; Evas_List *icons; - Evas_List *unsorted; + Evas_List *queue; + Ecore_Idler *scan_idler; + Ecore_Timer *scan_timer; + Ecore_Job *scroll_job; + Ecore_Job *resize_job; + DIR *dir; + unsigned char no_case_sort : 1; // unsigned char no_dnd : 1; // unsigned char single_select : 1; // unsigned char single_click : 1; @@ -37,7 +44,7 @@ struct _E_Fm2_Smart_Data struct _E_Fm2_Region { - E_Fm2_Smart_Data *smart; + E_Fm2_Smart_Data *sd; Evas_Coord x, y, w, h; Evas_List *list; unsigned char realized : 1; @@ -45,7 +52,7 @@ struct _E_Fm2_Region struct _E_Fm2_Icon { - E_Fm2_Smart_Data *smart; + E_Fm2_Smart_Data *sd; E_Fm2_Region *region; Evas_Coord x, y, w, h; Evas_Object *obj; @@ -57,15 +64,48 @@ struct _E_Fm2_Icon // unsigned char single_click : 1; }; -static void _e_fm2_smart_add(Evas_Object *object); -static void _e_fm2_smart_del(Evas_Object *object); -static void _e_fm2_smart_move(Evas_Object *object, Evas_Coord x, Evas_Coord y); -static void _e_fm2_smart_resize(Evas_Object *object, Evas_Coord w, Evas_Coord h); -static void _e_fm2_smart_show(Evas_Object *object); -static void _e_fm2_smart_hide(Evas_Object *object); -static void _e_fm2_smart_color_set(Evas_Object *obj, int r, int g, int b, int a); -static void _e_fm2_smart_clip_set(Evas_Object *obj, Evas_Object * clip); -static void _e_fm2_smart_clip_unset(Evas_Object *obj); +static char *_e_fm2_dev_path_map(char *dev, char *path); +static void _e_fm2_file_add(Evas_Object *obj, char *file); +static void _e_fm2_file_del(Evas_Object *obj, char *file); +static void _e_fm2_scan_start(Evas_Object *obj); +static void _e_fm2_scan_stop(Evas_Object *obj); +static void _e_fm2_queue_process(Evas_Object *obj); +static void _e_fm2_queue_free(Evas_Object *obj); +static void _e_fm2_regions_free(Evas_Object *obj); +static void _e_fm2_regions_populate(Evas_Object *obj); +static void _e_fm2_icons_place(Evas_Object *obj); +static void _e_fm2_icons_free(Evas_Object *obj); +static void _e_fm2_regions_eval(Evas_Object *obj); + +static E_Fm2_Icon *_e_fm2_icon_new(E_Fm2_Smart_Data *sd, char *file); +static void _e_fm2_icon_free(E_Fm2_Icon *ic); +static void _e_fm2_icon_realize(E_Fm2_Icon *ic); +static void _e_fm2_icon_unrealize(E_Fm2_Icon *ic); +static int _e_fm2_icon_visible(E_Fm2_Icon *ic); + +static E_Fm2_Region *_e_fm2_region_new(E_Fm2_Smart_Data *sd); +static void _e_fm2_region_free(E_Fm2_Region *rg); +static void _e_fm2_region_realize(E_Fm2_Region *rg); +static void _e_fm2_region_unrealize(E_Fm2_Region *rg); +static int _e_fm2_region_visible(E_Fm2_Region *rg); + +static void _e_fm2_cb_scroll_job(void *data); +static void _e_fm2_cb_resize_job(void *data); +static int _e_fm2_cb_icon_sort(void *data1, void *data2); +static int _e_fm2_cb_scan_idler(void *data); +static int _e_fm2_cb_scan_timer(void *data); + +static void _e_fm2_obj_icons_place(E_Fm2_Smart_Data *sd); + +static void _e_fm2_smart_add(Evas_Object *object); +static void _e_fm2_smart_del(Evas_Object *object); +static void _e_fm2_smart_move(Evas_Object *object, Evas_Coord x, Evas_Coord y); +static void _e_fm2_smart_resize(Evas_Object *object, Evas_Coord w, Evas_Coord h); +static void _e_fm2_smart_show(Evas_Object *object); +static void _e_fm2_smart_hide(Evas_Object *object); +static void _e_fm2_smart_color_set(Evas_Object *obj, int r, int g, int b, int a); +static void _e_fm2_smart_clip_set(Evas_Object *obj, Evas_Object * clip); +static void _e_fm2_smart_clip_unset(Evas_Object *obj); static char *_meta_path = NULL; static Evas_Smart *_e_fm2_smart = NULL; @@ -126,18 +166,25 @@ e_fm2_path_set(Evas_Object *obj, char *dev, char *path) if (!sd) return; // safety if (!evas_object_type_get(obj)) return; // safety if (strcmp(evas_object_type_get(obj), "e_fm")) return; // safety - if (sd->dev) free(sd->dev); - if (sd->path) free(sd->path); - // FIXME: nuke regions, icons etc. etc. - // dev == some system device or virtual filesystem eg: /dev/sda1 - // or /dev/hdc or /dev/dvd, /dev/cdrom etc. - // if it is NULL root fs is assumed. vfs's could be specified with - // music: for example or photos: etc. and soem vfs definition specifies - // how to map that vfs id to a list of files and subdirs + + /* we split up files into regions. each region can have a maximum of 128 + * icons and we realize/unrealize whole regions at once when that region + * becomes visible - this saves of object count and memory */ + sd->regions.member_max = 128; + + _e_fm2_scan_stop(obj); + _e_fm2_queue_free(obj); + _e_fm2_regions_free(obj); + _e_fm2_icons_free(obj); + E_FREE(sd->dev); + E_FREE(sd->path); + E_FREE(sd->realpath); if (dev) sd->dev = strdup(dev); sd->path = strdup(path); + sd->realpath = _e_fm2_dev_path_map(sd->dev, sd->path); // FIXME: begin dir scan/build - + printf("FM: %s\n", sd->realpath); + _e_fm2_scan_start(obj); } EAPI void @@ -155,19 +202,132 @@ e_fm2_path_get(Evas_Object *obj, char **dev, char **path) if (path) *path = sd->path; } +EAPI void +e_fm2_pan_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y) +{ + E_Fm2_Smart_Data *sd; + + sd = evas_object_smart_data_get(obj); + if (!sd) return; // safety + if (!evas_object_type_get(obj)) return; // safety + if (strcmp(evas_object_type_get(obj), "e_fm")) return; // safety + if ((sd->pos.x == x) && (sd->pos.y == y)) return; + sd->pos.x = x; + sd->pos.y = y; + printf("POS %i %i\n", x, y); + if (sd->scroll_job) ecore_job_del(sd->scroll_job); + sd->scroll_job = ecore_job_add(_e_fm2_cb_scroll_job, obj); +} + +EAPI void +e_fm2_pan_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y) +{ + E_Fm2_Smart_Data *sd; + + sd = evas_object_smart_data_get(obj); + if (!sd) return; // safety + if (!evas_object_type_get(obj)) return; // safety + if (strcmp(evas_object_type_get(obj), "e_fm")) return; // safety + if (x) *x = sd->pos.x; + if (y) *y = sd->pos.y; +} + +EAPI void +e_fm2_pan_max_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y) +{ + E_Fm2_Smart_Data *sd; + Evas_Coord mx, my; + + sd = evas_object_smart_data_get(obj); + if (!sd) return; // safety + if (!evas_object_type_get(obj)) return; // safety + if (strcmp(evas_object_type_get(obj), "e_fm")) return; // safety + mx = sd->max.w - sd->w; + if (mx < 0) mx = 0; + my = sd->max.h - sd->h; + if (my < 0) my = 0; + if (x) *x = mx; + if (y) *y = my; +} + +EAPI void +e_fm2_pan_child_size_get(Evas_Object *obj, Evas_Coord *w, Evas_Coord *h) +{ + E_Fm2_Smart_Data *sd; + + sd = evas_object_smart_data_get(obj); + if (!sd) return; // safety + if (!evas_object_type_get(obj)) return; // safety + if (strcmp(evas_object_type_get(obj), "e_fm")) return; // safety + if (w) *w = sd->max.w; + if (h) *h = sd->max.h; +} /* local subsystem functions */ +static char * +_e_fm2_dev_path_map(char *dev, char *path) +{ + char buf[4096] = "", *s; + int len; + + /* map a device name to a mount point/path on the os (and append path) */ + if (!dev) return strdup(path); + + /* FIXME: load mappings from config and use them first - maybe device + * discovery should be done through config and not the below (except + * maybe for home directory and root fs and other simple thngs */ + /* FIXME: also add other virtualized dirs like "backgrounds", "themes", + * "favorites" */ +#define CMP(x) (e_util_glob_case_match(dev, x)) +#define PRT(args...) snprintf(buf, sizeof(buf), ##args) + + if (CMP("/")) { + PRT("%s", path); + } + else if (CMP("~/")) { + s = e_user_homedir_get(); + PRT("%s%s", s, path); + free(s); + } + else if (CMP("dvd") || CMP("dvd-*")) { + /* FIXME: find dvd mountpoint optionally for dvd no. X */ + /* maybe make part of the device mappings config? */ + } + else if (CMP("cd") || CMP("cd-*") || CMP("cdrom") || CMP("cdrom-*") || + CMP("dvd") || CMP("dvd-*")) { + /* FIXME: find cdrom or dvd mountpoint optionally for cd/dvd no. X */ + /* maybe make part of the device mappings config? */ + } + /* FIXME: add code to find USB devices (multi-card readers or single, + * usb thumb drives, other usb storage devices (usb hd's etc.) + */ + /* maybe make part of the device mappings config? */ + /* FIXME: add code for finding nfs shares, smb shares etc. */ + /* maybe make part of the device mappings config? */ + + len = strlen(buf); + while ((len > 1) && (buf[len - 1] == '/')) + { + buf[len - 1] = 0; + len--; + } + return strdup(buf); +} + static void _e_fm2_file_add(Evas_Object *obj, char *file) { E_Fm2_Smart_Data *sd; + E_Fm2_Icon *ic; sd = evas_object_smart_data_get(obj); if (!sd) return; /* create icon obj and append to unsorted list */ + ic = _e_fm2_icon_new(sd, file); + sd->queue = evas_list_append(sd->queue, ic); } static void @@ -178,6 +338,58 @@ _e_fm2_file_del(Evas_Object *obj, char *file) sd = evas_object_smart_data_get(obj); if (!sd) return; /* find icon of file and remove from unsorted or main list */ + /* FIXME: find and remove */ +} + +static void +_e_fm2_scan_start(Evas_Object *obj) +{ + E_Fm2_Smart_Data *sd; + + sd = evas_object_smart_data_get(obj); + if (!sd) return; + /* start scanning the dir in an idler and putting found items on the */ + /* queue as icons - waiting for sorting and region insertion by a */ + /* timer that ticks off taking queued icons and putting them in a */ + /* sorted position in the icon list */ + /* this system is great - it completely does the dir scanning in idle + * time when e has nothing better to do - BUt it will mean that the dir + * will first draw with an empty view then slowly fill up as the scan + * happens - this means e remains interactive, but could mean for more + * redraws that we want. what we want to do is maybe bring some of the + * scan forward to here for a short period of time so when the window + * is drawn - its drawn with contents ... if they didnt take too long + * to fill + */ + /* if i add the above pre-scan and it doesnt finish - continue here */ + sd->scan_idler = ecore_idler_add(_e_fm2_cb_scan_idler, obj); + sd->scan_timer = ecore_timer_add(0.2, _e_fm2_cb_scan_timer, obj); +} + +static void +_e_fm2_scan_stop(Evas_Object *obj) +{ + E_Fm2_Smart_Data *sd; + + sd = evas_object_smart_data_get(obj); + if (!sd) return; + /* stop the scan idler, the sort timer and free the queue */ + if (sd->dir) + { + closedir(sd->dir); + sd->dir = NULL; + } + if (sd->scan_idler) + { + ecore_idler_del(sd->scan_idler); + sd->scan_idler = NULL; + } + if (sd->scan_timer) + { + ecore_timer_del(sd->scan_timer); + sd->scan_timer = NULL; + } + _e_fm2_queue_free(obj); } static void @@ -187,7 +399,35 @@ _e_fm2_queue_process(Evas_Object *obj) sd = evas_object_smart_data_get(obj); if (!sd) return; - /* take unsorted and insert into the regions */ + /* take unsorted and insert into the icon list - reprocess regions */ + while (sd->queue) + { + E_Fm2_Icon *ic; + + ic = sd->queue->data; + sd->icons = evas_list_append(sd->icons, ic); + /* insertion sort - better than qsort for the way we are doing + * things - incrimentally scan and sort as we go */ + sd->queue = evas_list_remove_list(sd->queue, sd->queue); + } + sd->icons = evas_list_sort(sd->icons, evas_list_count(sd->icons), _e_fm2_cb_icon_sort); + if (sd->resize_job) ecore_job_del(sd->resize_job); + sd->resize_job = ecore_job_add(_e_fm2_cb_resize_job, obj); +} + +static void +_e_fm2_queue_free(Evas_Object *obj) +{ + E_Fm2_Smart_Data *sd; + + sd = evas_object_smart_data_get(obj); + if (!sd) return; + /* just free the icons in the queue and the queue itself */ + while (sd->queue) + { + _e_fm2_icon_free(sd->queue->data); + sd->queue = evas_list_remove_list(sd->queue, sd->queue); + } } static void @@ -198,16 +438,111 @@ _e_fm2_regions_free(Evas_Object *obj) sd = evas_object_smart_data_get(obj); if (!sd) return; /* free up all regions */ + while (sd->regions.list) + { + _e_fm2_region_free(sd->regions.list->data); + sd->regions.list = evas_list_remove_list(sd->regions.list, sd->regions.list); + } } static void _e_fm2_regions_populate(Evas_Object *obj) { E_Fm2_Smart_Data *sd; + Evas_List *l; + E_Fm2_Region *rg; + E_Fm2_Icon *ic; sd = evas_object_smart_data_get(obj); if (!sd) return; /* take the icon list and split into regions */ + rg = NULL; + evas_event_freeze(evas_object_evas_get(obj)); + for (l = sd->icons; l; l = l->next) + { + ic = l->data; + if (!rg) + { + rg = _e_fm2_region_new(sd); + sd->regions.list = evas_list_append(sd->regions.list, rg); + } + ic->region = rg; + rg->list = evas_list_append(rg->list, ic); + if (rg->w == 0) + { + rg->x = ic->x; + rg->y = ic->y; + rg->w = ic->w; + rg->h = ic->h; + } + else + { + if (ic->x < rg->x) + { + rg->w += rg->x - ic->x; + rg->x = ic->x; + } + if ((ic->x + ic->w) > (rg->x + rg->w)) + { + rg->w += (ic->x + ic->w) - (rg->x + rg->w); + } + if (ic->y < rg->y) + { + rg->h += rg->y - ic->y; + rg->y = ic->y; + } + if ((ic->y + ic->h) > (rg->y + rg->h)) + { + rg->h += (ic->y + ic->h) - (rg->y + rg->h); + } + } + if (evas_list_count(rg->list) > sd->regions.member_max) + rg = NULL; + } + _e_fm2_regions_eval(obj); + for (l = sd->icons; l; l = l->next) + { + ic = l->data; + if ((!ic->region->realized) && (ic->realized)) + _e_fm2_icon_unrealize(ic); + } + printf("pop\n"); + _e_fm2_obj_icons_place(sd); + evas_event_thaw(evas_object_evas_get(obj)); +} + +static void +_e_fm2_icons_place(Evas_Object *obj) +{ + E_Fm2_Smart_Data *sd; + Evas_List *l; + E_Fm2_Icon *ic; + Evas_Coord x, y, rh; + + sd = evas_object_smart_data_get(obj); + if (!sd) return; + /* take the icon list and find a location for them */ + x = 0; y = 0; + rh = 0; + sd->max.w = 0; + sd->max.h = 0; + for (l = sd->icons; l; l = l->next) + { + ic = l->data; + if ((x > 0) && ((x + ic->w) > sd->w)) + { + x = 0; + y += rh; + rh = 0; + } + ic->x = x; + ic->y = y; + x += ic->w; + if (ic->h > rh) rh = ic->h; + if ((ic->x + ic->w) > sd->max.w) sd->max.w = ic->x + ic->w; + if ((ic->y + ic->h) > sd->max.h) sd->max.h = ic->y + ic->h; + } + evas_object_smart_callback_call(sd->obj, "changed", NULL); } static void @@ -217,9 +552,326 @@ _e_fm2_icons_free(Evas_Object *obj) sd = evas_object_smart_data_get(obj); if (!sd) return; + _e_fm2_queue_free(obj); /* free all icons */ + while (sd->icons) + { + _e_fm2_icon_free(sd->icons->data); + sd->icons = evas_list_remove_list(sd->icons, sd->icons); + } } +static void +_e_fm2_regions_eval(Evas_Object *obj) +{ + E_Fm2_Smart_Data *sd; + Evas_List *l; + E_Fm2_Region *rg; + + sd = evas_object_smart_data_get(obj); + if (!sd) return; + evas_event_freeze(evas_object_evas_get(obj)); + for (l = sd->regions.list; l; l = l->next) + { + rg = l->data; + + if (_e_fm2_region_visible(rg)) + _e_fm2_region_realize(rg); + else + _e_fm2_region_unrealize(rg); + } + evas_event_thaw(evas_object_evas_get(obj)); +} + +/**************************/ + +static E_Fm2_Icon * +_e_fm2_icon_new(E_Fm2_Smart_Data *sd, char *file) +{ + E_Fm2_Icon *ic; + + /* create icon */ + ic = E_NEW(E_Fm2_Icon, 1); + ic->sd = sd; + ic->file = strdup(file); + ic->w = 64; + ic->h = 64; + printf("FM: IC+ %s\n", ic->file); + return ic; +} + +static void +_e_fm2_icon_free(E_Fm2_Icon *ic) +{ + /* free icon, object data etc. etc. */ + _e_fm2_icon_unrealize(ic); + E_FREE(ic->file); + free(ic); +} + +static void +_e_fm2_icon_realize(E_Fm2_Icon *ic) +{ + if (ic->realized) return; + /* actually create evas objects etc. */ + ic->realized = 1; + evas_event_freeze(evas_object_evas_get(ic->sd->obj)); + ic->obj = edje_object_add(evas_object_evas_get(ic->sd->obj)); + evas_object_smart_member_add(ic->obj, ic->sd->obj); + edje_object_freeze(ic->obj); + e_theme_edje_object_set(ic->obj, "base/theme/fileman", + "fileman/icon_normal"); + evas_object_clip_set(ic->obj, ic->sd->clip); + evas_object_move(ic->obj, + ic->sd->x + ic->x - ic->sd->pos.x, + ic->sd->y + ic->y - ic->sd->pos.y); + evas_object_resize(ic->obj, ic->w, ic->h); + edje_object_part_text_set(ic->obj, "icon_title", ic->file); + edje_object_thaw(ic->obj); + evas_event_thaw(evas_object_evas_get(ic->sd->obj)); + evas_object_show(ic->obj); +} + +static void +_e_fm2_icon_unrealize(E_Fm2_Icon *ic) +{ + if (!ic->realized) return; + /* delete evas objects */ + ic->realized = 0; + evas_object_del(ic->obj); + ic->obj = NULL; +} + +static int +_e_fm2_icon_visible(E_Fm2_Icon *ic) +{ + /* return if the icon is visible */ + if ( + ((ic->x - ic->sd->pos.x) < (ic->sd->w)) && + ((ic->x + ic->w - ic->sd->pos.x) > 0) && + ((ic->y - ic->sd->pos.y) < (ic->sd->h)) && + ((ic->y + ic->h - ic->sd->pos.y) > 0) + ) + return 1; + return 0; +} + +/**************************/ +static E_Fm2_Region * +_e_fm2_region_new(E_Fm2_Smart_Data *sd) +{ + E_Fm2_Region *rg; + + rg = E_NEW(E_Fm2_Region, 1); + rg->sd = sd; + return rg; +} + +static void +_e_fm2_region_free(E_Fm2_Region *rg) +{ + E_Fm2_Icon *ic; + + while (rg->list) + { + ic = rg->list->data; + ic->region = NULL; + rg->list = evas_list_remove_list(rg->list, rg->list); + } + free(rg); +} + +static void +_e_fm2_region_realize(E_Fm2_Region *rg) +{ + Evas_List *l; + + if (rg->realized) return; + /* actually create evas objects etc. */ + rg->realized = 1; + printf("REG %p REALIZE\n", rg); + for (l = rg->list; l; l = l->next) _e_fm2_icon_realize(l->data); +} + +static void +_e_fm2_region_unrealize(E_Fm2_Region *rg) +{ + Evas_List *l; + + if (!rg->realized) return; + /* delete evas objects */ + rg->realized = 0; + printf("REG %p UNREALIZE\n", rg); + for (l = rg->list; l; l = l->next) _e_fm2_icon_unrealize(l->data); +} + +static int +_e_fm2_region_visible(E_Fm2_Region *rg) +{ + /* return if the icon is visible */ + if ( + ((rg->x - rg->sd->pos.x) < (rg->sd->w)) && + ((rg->x + rg->w - rg->sd->pos.x) > 0) && + ((rg->y - rg->sd->pos.y) < (rg->sd->h)) && + ((rg->y + rg->h - rg->sd->pos.y) > 0) + ) + return 1; + return 0; +} + +/**************************/ + +static void +_e_fm2_cb_scroll_job(void *data) +{ + E_Fm2_Smart_Data *sd; + + sd = evas_object_smart_data_get(data); + if (!sd) return; + sd->scroll_job = NULL; + printf("DO scroll!\n"); + evas_event_freeze(evas_object_evas_get(sd->obj)); + _e_fm2_regions_eval(sd->obj); + _e_fm2_obj_icons_place(sd); + evas_event_thaw(evas_object_evas_get(sd->obj)); +} + +static void +_e_fm2_cb_resize_job(void *data) +{ + E_Fm2_Smart_Data *sd; + + sd = evas_object_smart_data_get(data); + if (!sd) return; + sd->resize_job = NULL; + evas_event_freeze(evas_object_evas_get(sd->obj)); + _e_fm2_regions_free(sd->obj); + _e_fm2_icons_place(sd->obj); + _e_fm2_regions_populate(sd->obj); + evas_event_thaw(evas_object_evas_get(sd->obj)); +} + +static int +_e_fm2_cb_icon_sort(void *data1, void *data2) +{ + E_Fm2_Icon *ic1, *ic2; + + ic1 = data1; + ic2 = data2; + if (ic1->sd->no_case_sort) + { + char buf1[4096], buf2[4096], *p; + + strncpy(buf1, ic1->file, sizeof(buf1) - 2); + strncpy(buf2, ic2->file, sizeof(buf2) - 2); + buf1[sizeof(buf1) - 1] = 0; + buf2[sizeof(buf2) - 1] = 0; + p = buf1; + while (*p) + { + *p = tolower(*p); + p++; + } + p = buf2; + while (*p) + { + *p = tolower(*p); + p++; + } + return strcmp(buf1, buf2); + } + return strcmp(ic1->file, ic2->file); +} + +static int +_e_fm2_cb_scan_idler(void *data) +{ + E_Fm2_Smart_Data *sd; + struct dirent *dp; + + sd = evas_object_smart_data_get(data); + if (!sd) return 0; + if (!sd->dir) sd->dir = opendir(sd->realpath); + if (!sd->dir) goto endscan; + + dp = readdir(sd->dir); + if (!dp) goto endscan; + /* no - you don't want the cuirrent and parent dir links listed */ + if ((!strcmp(dp->d_name, ".")) || (!strcmp(dp->d_name, ".."))) return 1; + /* skip dotfiles */ + if (dp->d_name[0] == '.') return 1; + _e_fm2_file_add(data, dp->d_name); + return 1; + + endscan: + if (sd->dir) + { + closedir(sd->dir); + sd->dir = NULL; + } + sd->scan_idler = NULL; + if (sd->scan_timer) + { + ecore_timer_del(sd->scan_timer); + sd->scan_timer = ecore_timer_add(0.0001, _e_fm2_cb_scan_timer, sd->obj); + } + return 0; +} + +static int +_e_fm2_cb_scan_timer(void *data) +{ + E_Fm2_Smart_Data *sd; + + sd = evas_object_smart_data_get(data); + if (!sd) return 0; + _e_fm2_queue_process(data); + if (!sd->scan_idler) + { + Evas_List *l; + + /* we finished scanning! */ + for (l = sd->icons; l; l = l->next) + { + E_Fm2_Icon *ic; + + ic = l->data; + printf("FM: IC: %i %i, %s\n", ic->x, ic->y, ic->file); + } + sd->scan_timer = NULL; + return 0; + } + return 1; +} + +/**************************/ +static void +_e_fm2_obj_icons_place(E_Fm2_Smart_Data *sd) +{ + Evas_List *l, *ll; + E_Fm2_Region *rg; + E_Fm2_Icon *ic; + + evas_event_freeze(evas_object_evas_get(sd->obj)); + for (l = sd->regions.list; l; l = l->next) + { + rg = l->data; + if (rg->realized) + { + for (ll = rg->list; ll; ll = ll->next) + { + ic = ll->data; + if (ic->realized) + evas_object_move(ic->obj, + sd->x + ic->x - sd->pos.x, + sd->y + ic->y - sd->pos.y); + } + } + } + evas_event_thaw(evas_object_evas_get(sd->obj)); +} + +/**************************/ static void _e_fm2_smart_add(Evas_Object *obj) @@ -246,7 +898,17 @@ _e_fm2_smart_del(Evas_Object *obj) sd = evas_object_smart_data_get(obj); if (!sd) return; - + + _e_fm2_scan_stop(obj); + _e_fm2_queue_free(obj); + _e_fm2_regions_free(obj); + _e_fm2_icons_free(obj); + if (sd->scroll_job) ecore_job_del(sd->scroll_job); + if (sd->resize_job) ecore_job_del(sd->resize_job); + E_FREE(sd->dev); + E_FREE(sd->path); + E_FREE(sd->realpath); + evas_object_del(sd->clip); free(sd); } @@ -258,23 +920,40 @@ _e_fm2_smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y) sd = evas_object_smart_data_get(obj); if (!sd) return; - if ((sd->x == x) || (sd->y == y)) return; + if ((sd->x == x) && (sd->y == y)) return; sd->x = x; sd->y = y; evas_object_move(sd->clip, x, y); + printf("mov\n"); + _e_fm2_obj_icons_place(sd); } static void _e_fm2_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h) { E_Fm2_Smart_Data *sd; + int wch = 0, hch = 0; sd = evas_object_smart_data_get(obj); if (!sd) return; - if ((sd->w == w) || (sd->h == h)) return; + if ((sd->w == w) && (sd->h == h)) return; + if (w != sd->w) wch = 1; + if (h != sd->h) hch = 1; sd->w = w; sd->h = h; evas_object_resize(sd->clip, w, h); + + /* for automatic layout - do this - NB; we could put this on a timer delay */ + if (wch) + { + if (sd->resize_job) ecore_job_del(sd->resize_job); + sd->resize_job = ecore_job_add(_e_fm2_cb_resize_job, obj); + } + else + { + if (sd->scroll_job) ecore_job_del(sd->scroll_job); + sd->scroll_job = ecore_job_add(_e_fm2_cb_scroll_job, obj); + } } static void diff --git a/src/bin/e_fm.h b/src/bin/e_fm.h index 6ed32712f..6fa2cec7f 100644 --- a/src/bin/e_fm.h +++ b/src/bin/e_fm.h @@ -7,8 +7,8 @@ typedef enum _E_Fm2_View_Mode { - E_FM_VIEW_MODE_ICONS, - E_FM_VIEW_MODE_LIST + E_FM2_VIEW_MODE_ICONS, + E_FM2_VIEW_MODE_LIST } E_Fm2_View_Mode; #else @@ -20,6 +20,12 @@ EAPI int e_fm2_shutdown(void); EAPI Evas_Object *e_fm2_add(Evas *evas); EAPI void e_fm2_path_set(Evas_Object *obj, char *dev, char *path); EAPI void e_fm2_path_get(Evas_Object *obj, char **dev, char **path); - + +EAPI void e_fm2_pan_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y); +EAPI void e_fm2_pan_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y); +EAPI void e_fm2_pan_max_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y); +EAPI void e_fm2_pan_child_size_get(Evas_Object *obj, Evas_Coord *w, Evas_Coord *h); + + #endif #endif diff --git a/src/bin/e_test.c b/src/bin/e_test.c index 6bb38ee99..10a34b706 100644 --- a/src/bin/e_test.c +++ b/src/bin/e_test.c @@ -589,21 +589,27 @@ static void _e_test_internal(E_Container *con) { E_Dialog *dia; - Evas_Object *o; - Evas_Coord mw, mh; + Evas_Object *o, *o2; dia = e_dialog_new(con); e_dialog_title_set(dia, "A Test Dialog"); o = e_fm2_add(dia->win->evas); - e_fm2_path_set(o, "~/", "/"); + e_fm2_path_set(o, NULL, "/dev"); evas_object_show(o); - e_dialog_content_set(dia, o, 480, 320); + o2 = e_scrollframe_add(dia->win->evas); + evas_object_show(o2); + e_scrollframe_extern_pan_set(o2, o, + e_fm2_pan_set, e_fm2_pan_get, + e_fm2_pan_max_get, e_fm2_pan_child_size_get); + e_dialog_content_set(dia, o2, 64, 64); e_dialog_button_add(dia, "OK", NULL, NULL, NULL); + e_dialog_resizable_set(dia, 1); e_win_centered_set(dia->win, 1); e_dialog_show(dia); + e_win_resize(dia->win, 400, 300); evas_object_focus_set(o, 1); } diff --git a/src/bin/e_user.c b/src/bin/e_user.c index 1512bbd11..5d889d1c5 100644 --- a/src/bin/e_user.c +++ b/src/bin/e_user.c @@ -8,8 +8,15 @@ EAPI char * e_user_homedir_get(void) { char *homedir; + int len; homedir = getenv("HOME"); if (!homedir) return strdup("/tmp"); + len = strlen(homedir); + while ((len > 1) && (homedir[len - 1] == '/')) + { + homedir[len - 1] = 0; + len--; + } return strdup(homedir); }