280 lines
8.0 KiB
C
280 lines
8.0 KiB
C
// utils for draga and drop handling
|
|
static Eina_Bool
|
|
_cb_dnd_scroll_timer(void *data)
|
|
{
|
|
Smart_Data *sd = data;
|
|
Evas_Coord fmx, fmy, sx, sy, sw, sh, x, y;
|
|
Evas_Coord scr_edge_x, scr_edge_y, scr_mul;
|
|
|
|
evas_object_geometry_get(sd->o_smart, &fmx, &fmy, NULL, NULL);
|
|
evas_object_geometry_get(sd->o_scroller, &sx, &sy, &sw, &sh);
|
|
scr_mul = 4;
|
|
scr_edge_x = sd->icon_min_w / 2;
|
|
scr_edge_y = sd->icon_min_h / 2;
|
|
if (sd->dnd_scroll_x < scr_edge_x)
|
|
x = sx - fmx + sd->dnd_scroll_x - scr_edge_x - ((scr_edge_x - sd->dnd_scroll_x) * scr_mul);
|
|
else if (sd->dnd_scroll_x > (sw - scr_edge_x))
|
|
x = sx - fmx + sd->dnd_scroll_x + scr_edge_x + ((sd->dnd_scroll_x - (sw - scr_edge_x)) * scr_mul);
|
|
else
|
|
x = sx - fmx + sd->dnd_scroll_x;
|
|
if (sd->dnd_scroll_y < scr_edge_y)
|
|
y = sy - fmy + sd->dnd_scroll_y - scr_edge_y - ((scr_edge_y - sd->dnd_scroll_y) * scr_mul);
|
|
else if (sd->dnd_scroll_y > (sh - scr_edge_y))
|
|
y = sy - fmy + sd->dnd_scroll_y + scr_edge_y + ((sd->dnd_scroll_y - (sh - scr_edge_y)) * scr_mul);
|
|
else
|
|
y = sy - fmy + sd->dnd_scroll_y;
|
|
printf("SSS %i %i | %i %i %ix%i | %i %i\n", x, y, sx, sy, sw, sh, sd->dnd_scroll_x, sd->dnd_scroll_y);
|
|
elm_scroller_region_bring_in(sd->o_scroller, x, y, 1, 1);
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
static void
|
|
_dnd_scroll_handle(Smart_Data *sd, Evas_Coord x, Evas_Coord y)
|
|
{
|
|
sd->dnd_scroll_x = x;
|
|
sd->dnd_scroll_y = y;
|
|
if (!sd->dnd_scroll_timer)
|
|
sd->dnd_scroll_timer = ecore_timer_add
|
|
(SCROLL_DND_TIMER, _cb_dnd_scroll_timer, sd);
|
|
}
|
|
|
|
static void
|
|
_dnd_scroll_end_handle(Smart_Data *sd)
|
|
{
|
|
if (sd->dnd_scroll_timer)
|
|
{
|
|
ecore_timer_del(sd->dnd_scroll_timer);
|
|
sd->dnd_scroll_timer = NULL;
|
|
}
|
|
}
|
|
|
|
static void
|
|
_dnd_over(Icon *icon)
|
|
{
|
|
_icon_over_on(icon);
|
|
}
|
|
|
|
static void
|
|
_dnd_over_none_handle(Smart_Data *sd)
|
|
{
|
|
if (sd->over_icon) _icon_over_off(sd->over_icon);
|
|
}
|
|
|
|
static void
|
|
_dnd_over_handle(Smart_Data *sd, Evas_Coord x, Evas_Coord y)
|
|
{
|
|
Icon *icon;
|
|
Eina_List *bl, *il;
|
|
Block *block;
|
|
|
|
EINA_LIST_FOREACH(sd->blocks, bl, block)
|
|
{
|
|
if (!eina_rectangle_coords_inside(&(block->bounds), x, y)) continue;
|
|
EINA_LIST_FOREACH(block->icons, il, icon)
|
|
{
|
|
if (!eina_rectangle_coords_inside(&(icon->geom), x, y)) continue;
|
|
_dnd_over(icon);
|
|
return;
|
|
}
|
|
}
|
|
_dnd_over_none_handle(sd);
|
|
}
|
|
|
|
// drop handling
|
|
static void
|
|
_cb_drop_in(void *data EINA_UNUSED, Evas_Object *o EINA_UNUSED)
|
|
{
|
|
// Smart_Data *sd = data;
|
|
printf("XXX: drop in.....\n");
|
|
// XXX: call drop in smart callback}
|
|
}
|
|
|
|
static void
|
|
_cb_drop_out(void *data, Evas_Object *o EINA_UNUSED)
|
|
{
|
|
Smart_Data *sd = data;
|
|
_dnd_scroll_end_handle(sd);
|
|
_dnd_over_none_handle(sd);
|
|
printf("XXX: drop out.....\n");
|
|
// XXX: call drop out smart callback}
|
|
}
|
|
|
|
void
|
|
_cb_drop_pos(void *data, Evas_Object *o EINA_UNUSED, Evas_Coord x, Evas_Coord y, Elm_Xdnd_Action action EINA_UNUSED)
|
|
{
|
|
Smart_Data *sd = data;
|
|
Evas_Coord fmx, fmy, fmw, fmh;
|
|
Evas_Coord sx, sy, sw, sh;
|
|
|
|
sd->dnd_action = action;
|
|
evas_object_geometry_get(sd->o_smart, &fmx, &fmy, &fmw, &fmh);
|
|
evas_object_geometry_get(sd->o_scroller, &sx, &sy, &sw, &sh);
|
|
_dnd_scroll_handle(sd, x - sx, y - sy);
|
|
if (((x - sx) > 0) && ((y - sy) > 0) &&
|
|
((x - sx) < sw) && ((y - sy) < sh))
|
|
_dnd_over_handle(sd, x - fmx, y - fmy);
|
|
else
|
|
_dnd_over_none_handle(sd);
|
|
if (sd->over_icon) sd->drop_over = sd->over_icon;
|
|
else sd->drop_over = NULL;
|
|
}
|
|
|
|
static Eina_Bool
|
|
_cb_drop(void *data, Evas_Object *o EINA_UNUSED, Elm_Selection_Data *ev)
|
|
{
|
|
Smart_Data *sd = data;
|
|
char **plist, **p, *esc, *tmp;
|
|
|
|
if (sd->drop_over) printf("XXX: DND DROP OVER [%s]\n", sd->drop_over->info.file);
|
|
else printf("XXX: DND DROP ...\n");
|
|
tmp = malloc(ev->len + 1);
|
|
if (!tmp) goto err;
|
|
memcpy(tmp, ev->data, ev->len);
|
|
tmp[ev->len] = 0;
|
|
plist = eina_str_split(tmp, "\n", -1);
|
|
for (p = plist; *p != NULL; ++p)
|
|
{
|
|
if (**p)
|
|
{
|
|
esc = _escape_parse(*p);
|
|
if (!esc) continue;
|
|
printf("XXX: DROP FILE: [%s]\n", esc);
|
|
}
|
|
}
|
|
free(*plist);
|
|
free(plist);
|
|
free(tmp);
|
|
err:
|
|
sd->drop_over = NULL;
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
static void
|
|
_drop_init(Smart_Data *sd)
|
|
{ // called once we have our elm scroller around our file view
|
|
elm_drop_target_add(sd->o_scroller,
|
|
ELM_SEL_FORMAT_URILIST,
|
|
_cb_drop_in, sd,
|
|
_cb_drop_out, sd,
|
|
_cb_drop_pos, sd,
|
|
_cb_drop, sd);
|
|
}
|
|
|
|
// drag handling
|
|
static Evas_Object *
|
|
_cb_drag_icon_add(void *data, Evas_Object *parent, Evas_Coord *xoff, Evas_Coord *yoff)
|
|
{
|
|
Icon *icon = data;
|
|
Icon *icon2;
|
|
Block *block;
|
|
Evas_Object *obj = icon->sd->o_smart;
|
|
Evas_Object *o;
|
|
const char *theme_edj_file;
|
|
Evas *e;
|
|
ENTRY NULL;
|
|
Eina_List *bl, *il;
|
|
int num = 0;
|
|
|
|
if (sd->config.view_mode >= EFM_VIEW_MODE_LIST)
|
|
{
|
|
EINA_LIST_FOREACH(sd->blocks, bl, block)
|
|
{
|
|
if (block->realized_num <= 0)
|
|
{
|
|
num += eina_list_count(block->icons);
|
|
continue;
|
|
}
|
|
EINA_LIST_FOREACH(block->icons, il, icon2)
|
|
{
|
|
if (icon == icon2) goto found;
|
|
num++;
|
|
}
|
|
num += eina_list_count(block->icons);
|
|
}
|
|
}
|
|
found:
|
|
e = evas_object_evas_get(parent);
|
|
theme_edj_file = elm_theme_group_path_find(NULL,
|
|
"e/fileman/default/icon/fixed");
|
|
_icon_object_add(icon, icon->sd, e, theme_edj_file, EINA_FALSE, num);
|
|
o = icon->o_base;
|
|
evas_object_resize(o, icon->geom.w, icon->geom.h);
|
|
if (xoff) *xoff = (icon->geom.x + icon->sd->geom.x);
|
|
if (yoff) *yoff = (icon->geom.y + icon->sd->geom.y);
|
|
if (xoff && yoff)
|
|
printf("DND: drag begin %p %p off: %i %i\n", obj, o, *xoff, *yoff);
|
|
else
|
|
printf("DND: drag begin %p %p\n", obj, o);
|
|
return o;
|
|
}
|
|
|
|
static void
|
|
_cb_drag_pos(void *data EINA_UNUSED, Evas_Object *obj_drag EINA_UNUSED, Evas_Coord x, Evas_Coord y, Elm_Xdnd_Action action)
|
|
{
|
|
printf("DND: %i %i act=%i\n", x, y, action);
|
|
}
|
|
|
|
static void
|
|
_cb_drag_accept(void *data EINA_UNUSED, Evas_Object *obj_drag EINA_UNUSED, Eina_Bool accept)
|
|
{
|
|
printf("DND: accept %i\n", accept);
|
|
}
|
|
|
|
static void
|
|
_cb_drag_done(void *data, Evas_Object *obj_drag EINA_UNUSED)
|
|
{
|
|
Icon *icon = data;
|
|
Evas_Object *obj;
|
|
|
|
if (icon->sd)
|
|
{
|
|
obj = icon->sd->o_smart;
|
|
ENTRY;
|
|
|
|
printf("DND: drag done %p %p\n", obj, obj_drag);
|
|
sd->drag = EINA_FALSE;
|
|
icon->o_base = NULL; // try and not del this as dnd will do it
|
|
icon->sd->drag_icon = NULL;
|
|
}
|
|
_icon_free(icon);
|
|
}
|
|
|
|
static void
|
|
_drag_start(Icon *icon)
|
|
{
|
|
Eina_Strbuf *strbuf;
|
|
Icon *icon_dup;
|
|
|
|
strbuf = eina_strbuf_new();
|
|
if (!strbuf) return;
|
|
icon_dup = _icon_dup(icon);
|
|
if (!icon_dup) goto err;
|
|
|
|
if (icon->sd->rename_icon) _icon_rename_end(icon->sd->rename_icon);
|
|
printf("XXX: begin dnd\n");
|
|
|
|
icon->sd->drag = EINA_TRUE;
|
|
icon->sd->just_dragged = EINA_TRUE;
|
|
icon->sd->drag_icon = icon_dup;
|
|
if (_selected_icons_uri_strbuf_append(icon->sd, strbuf))
|
|
{ // begin the drag with that list of files
|
|
// XXX: if you use no modifier - do default (move)
|
|
// XXX: if you hold ctrl then do copy
|
|
// XXX: on win ... to/from removable drive it copies always
|
|
// XXX: if you hold shift then do move
|
|
// XXX; on mac option key forces a copy normally except from
|
|
// removable device then it forces a move
|
|
// XXX: this "except to/from removable drive" is bad/inconsistent imho
|
|
elm_drag_start(icon_dup->sd->o_scroller,
|
|
ELM_SEL_FORMAT_URILIST,
|
|
eina_strbuf_string_get(strbuf),
|
|
ELM_XDND_ACTION_MOVE,
|
|
_cb_drag_icon_add, icon_dup,
|
|
_cb_drag_pos, icon_dup,
|
|
_cb_drag_accept, icon_dup,
|
|
_cb_drag_done, icon_dup);
|
|
}
|
|
err:
|
|
eina_strbuf_free(strbuf);
|
|
}
|