forked from enlightenment/efl
flesh out a lot more of dnd support in elm and add apis to set up dnd
targets for objects as well as initiate a dnd. SVN revision: 84282
This commit is contained in:
parent
458faf56a3
commit
3091ccc3f6
|
@ -1051,3 +1051,8 @@
|
|||
|
||||
* Fix gl engine vsync option pass-in in elm_win
|
||||
* Fix elm_progressbar_pulse() to abort if pulsing not enabled
|
||||
|
||||
2013-02-21 Carsten Haitzler (The Rasterman)
|
||||
|
||||
* Improve a lot of the dnd infra to be more fully baked
|
||||
* Add elm_drop_target_add() elm_drop_target_del() and elm_drag_start()
|
||||
|
|
|
@ -40,6 +40,7 @@ Additions:
|
|||
* Add the reorder effect in toolbar.
|
||||
* Added new APIs elm_transit_tween_mode_facator_set()/get()
|
||||
* Support widget orientation mode in order to widgets have multiple styles for each window degree.
|
||||
* Add elm_drop_target_add() elm_drop_target_del() and elm_drag_start()
|
||||
|
||||
Improvements:
|
||||
|
||||
|
|
|
@ -71,8 +71,18 @@ struct _Dropable
|
|||
Evas_Object *obj;
|
||||
/* FIXME: Cache window */
|
||||
Elm_Sel_Format types;
|
||||
Elm_Drag_State entercb;
|
||||
Elm_Drag_State leavecb;
|
||||
Elm_Drag_Pos poscb;
|
||||
Elm_Drop_Cb dropcb;
|
||||
void *enterdata;
|
||||
void *leavedata;
|
||||
void *posdata;
|
||||
void *cbdata;
|
||||
struct {
|
||||
Evas_Coord x, y;
|
||||
Eina_Bool in : 1;
|
||||
} last;
|
||||
};
|
||||
|
||||
static int _elm_cnp_init_count = 0;
|
||||
|
@ -94,13 +104,14 @@ static Ecore_Event_Handler *handler_pos = NULL;
|
|||
static Ecore_Event_Handler *handler_drop = NULL;
|
||||
static Ecore_Event_Handler *handler_enter = NULL;
|
||||
static Ecore_Event_Handler *handler_status = NULL;
|
||||
static Ecore_Event_Handler *handler_leave = NULL;
|
||||
static Ecore_Event_Handler *handler_up = NULL;
|
||||
|
||||
static Tmp_Info *_tempfile_new (int size);
|
||||
static int _tmpinfo_free (Tmp_Info *tmp);
|
||||
static Eina_Bool _pasteimage_append (char *file, Evas_Object *entry);
|
||||
|
||||
#define DEBUGON 1
|
||||
//#define DEBUGON 1
|
||||
#ifdef DEBUGON
|
||||
# define cnp_debug(x...) fprintf(stderr, __FILE__": " x)
|
||||
#else
|
||||
|
@ -174,6 +185,7 @@ static Eina_Bool _x11_dnd_enter (void *data __UNUSED__, int
|
|||
static Eina_Bool _x11_dnd_drop (void *data __UNUSED__, int etype __UNUSED__, void *ev);
|
||||
static Eina_Bool _x11_dnd_position (void *data __UNUSED__, int etype __UNUSED__, void *ev);
|
||||
static Eina_Bool _x11_dnd_status (void *data __UNUSED__, int etype __UNUSED__, void *ev);
|
||||
static Eina_Bool _x11_dnd_leave (void *data __UNUSED__, int etype __UNUSED__, void *ev);
|
||||
static Eina_Bool _x11_drag_mouse_up (void *data, int etype __UNUSED__, void *event);
|
||||
static void _x11_drag_move (void *data __UNUSED__, Ecore_X_Xdnd_Position *pos);
|
||||
|
||||
|
@ -184,7 +196,11 @@ static Eina_Bool _x11_elm_cnp_selection_set (Evas_Object *obj, Elm_
|
|||
static void _x11_elm_cnp_selection_loss_callback_set(Evas_Object *obj __UNUSED__, Elm_Sel_Type selection, Elm_Selection_Loss_Cb func, const void *data);
|
||||
static Eina_Bool _x11_elm_object_cnp_selection_clear (Evas_Object *obj, Elm_Sel_Type selection);
|
||||
static Eina_Bool _x11_elm_cnp_selection_get (Evas_Object *obj, Elm_Sel_Type selection, Elm_Sel_Format format, Elm_Drop_Cb datacb, void *udata);
|
||||
static Eina_Bool _x11_elm_drop_target_add (Evas_Object *obj, Elm_Sel_Format format, Elm_Drop_Cb dropcb, void *cbdata);
|
||||
static Eina_Bool _x11_elm_drop_target_add (Evas_Object *obj, Elm_Sel_Format format,
|
||||
Elm_Drag_State entercb, void *enterdata,
|
||||
Elm_Drag_State leavecb, void *leavedata,
|
||||
Elm_Drag_Pos poscb, void *posdata,
|
||||
Elm_Drop_Cb dropcb, void *cbdata);
|
||||
static Eina_Bool _x11_elm_drop_target_del (Evas_Object *obj);
|
||||
static Eina_Bool _x11_elm_selection_selection_has_owner (Evas_Object *obj __UNUSED__);
|
||||
|
||||
|
@ -1011,14 +1027,82 @@ _x11_general_converter(char *target __UNUSED__, void *data, int size, void **dat
|
|||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static Dropable *
|
||||
_x11_dropable_find(Ecore_X_Window win)
|
||||
{
|
||||
Eina_List *l;
|
||||
Dropable *dropable;
|
||||
|
||||
if (!drops) return NULL;
|
||||
EINA_LIST_FOREACH(drops, l, dropable)
|
||||
{
|
||||
if (_x11_elm_widget_xwin_get(dropable->obj) == win) return dropable;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static Dropable *
|
||||
_x11_dropable_geom_find(Ecore_X_Window win, Evas_Coord px, Evas_Coord py)
|
||||
{
|
||||
Eina_List *l;
|
||||
Dropable *dropable;
|
||||
Evas_Coord x, y, w, h;
|
||||
|
||||
if (!drops) return NULL;
|
||||
EINA_LIST_FOREACH(drops, l, dropable)
|
||||
{
|
||||
if (_x11_elm_widget_xwin_get(dropable->obj) == win)
|
||||
{
|
||||
evas_object_geometry_get(dropable->obj, &x, &y, &w, &h);
|
||||
if ((px >= x) && (py >= y) && (px < (x + w)) && (py < (y + h)))
|
||||
return dropable;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
_x11_dropable_coords_adjust(Dropable *dropable, Evas_Coord *x, Evas_Coord *y)
|
||||
{
|
||||
Ecore_Evas *ee;
|
||||
int ex = 0, ey = 0;
|
||||
|
||||
ee = ecore_evas_ecore_evas_get(evas_object_evas_get(dropable->obj));
|
||||
ecore_evas_geometry_get(ee, &ex, &ey, NULL, NULL);
|
||||
*x = *x - ex;
|
||||
*y = *y - ey;
|
||||
}
|
||||
|
||||
static void
|
||||
_x11_dropable_all_set(Ecore_X_Window win, Evas_Coord x, Evas_Coord y, Eina_Bool set)
|
||||
{
|
||||
Eina_List *l;
|
||||
Dropable *dropable;
|
||||
EINA_LIST_FOREACH(drops, l, dropable)
|
||||
{
|
||||
if (_x11_elm_widget_xwin_get(dropable->obj) == win)
|
||||
{
|
||||
dropable->last.x = x;
|
||||
dropable->last.y = y;
|
||||
dropable->last.in = set;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_x11_dnd_enter(void *data __UNUSED__, int etype __UNUSED__, void *ev)
|
||||
{
|
||||
Ecore_X_Event_Xdnd_Enter *enter = ev;
|
||||
int i;
|
||||
Dropable *dropable;
|
||||
|
||||
dropable = _x11_dropable_find(enter->win);
|
||||
if (dropable)
|
||||
{
|
||||
cnp_debug("Enter %x\n", enter->win);
|
||||
_x11_dropable_all_set(enter->win, 0, 0, EINA_FALSE);
|
||||
}
|
||||
/* Skip it */
|
||||
cnp_debug("enter %p\n", enter);
|
||||
cnp_debug("enter types=%p (%d)\n", enter->types, enter->num_types);
|
||||
if ((!enter) || (!enter->num_types) || (!enter->types)) return EINA_TRUE;
|
||||
|
||||
|
@ -1048,61 +1132,142 @@ _x11_dnd_enter(void *data __UNUSED__, int etype __UNUSED__, void *ev)
|
|||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
_x11_dnd_dropable_handle(Dropable *dropable, Evas_Coord x, Evas_Coord y, Eina_Bool have_obj)
|
||||
{
|
||||
Dropable *dropable_last = NULL;
|
||||
|
||||
if (dropable->last.in)
|
||||
dropable_last = _x11_dropable_geom_find
|
||||
(_x11_elm_widget_xwin_get(dropable->obj),
|
||||
dropable->last.x, dropable->last.y);
|
||||
if ((have_obj) && (dropable_last == dropable)) // same
|
||||
{
|
||||
cnp_debug("same obj dropable %p\n", dropable);
|
||||
if (dropable->poscb)
|
||||
dropable->poscb(dropable->posdata, dropable->obj, x, y);
|
||||
}
|
||||
else if ((have_obj) && (!dropable_last)) // enter new obj
|
||||
{
|
||||
cnp_debug("enter %p\n", dropable->obj);
|
||||
if (dropable->entercb)
|
||||
dropable->entercb(dropable->enterdata, dropable->obj);
|
||||
if (dropable->poscb)
|
||||
dropable->poscb(dropable->posdata, dropable->obj, x, y);
|
||||
}
|
||||
else if ((!have_obj) && (dropable_last)) // leave last obj
|
||||
{
|
||||
cnp_debug("leave %p\n", dropable_last->obj);
|
||||
if (dropable->leavecb)
|
||||
dropable->leavecb(dropable->leavedata, dropable->obj);
|
||||
}
|
||||
else if (have_obj) // leave last obj and enter new one
|
||||
{
|
||||
cnp_debug("enter %p\n", dropable->obj);
|
||||
if (dropable->entercb)
|
||||
dropable->entercb(dropable->enterdata, dropable->obj);
|
||||
if (dropable_last)
|
||||
{
|
||||
dropable = dropable_last;
|
||||
if (dropable->leavecb)
|
||||
dropable->leavecb(dropable->leavedata, dropable->obj);
|
||||
cnp_debug("leave %p\n", dropable->obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_x11_dnd_position(void *data __UNUSED__, int etype __UNUSED__, void *ev)
|
||||
{
|
||||
Ecore_X_Event_Xdnd_Position *pos = ev;
|
||||
Ecore_X_Rectangle rect;
|
||||
Dropable *dropable, *dropable_old;
|
||||
|
||||
/* Need to send a status back */
|
||||
/* FIXME: Should check I can drop here */
|
||||
/* FIXME: Should highlight widget */
|
||||
dropable_old = dropable = _x11_dropable_find(pos->win);
|
||||
if (dropable)
|
||||
{
|
||||
Evas_Coord x, y, ox = 0, oy = 0, ow = 0, oh = 0;
|
||||
|
||||
x = pos->position.x;
|
||||
y = pos->position.y;
|
||||
_x11_dropable_coords_adjust(dropable, &x, &y);
|
||||
dropable = _x11_dropable_geom_find(pos->win, x, y);
|
||||
if (dropable)
|
||||
{
|
||||
evas_object_geometry_get(dropable->obj, &ox, &oy, &ow, &oh);
|
||||
rect.x = pos->position.x - x + ox;
|
||||
rect.y = pos->position.y - y + oy;
|
||||
rect.width = ow;
|
||||
rect.height = oh;
|
||||
ecore_x_dnd_send_status(EINA_TRUE, EINA_FALSE, rect, pos->action);
|
||||
cnp_debug("dnd position %i %i %p\n", x - ox, y - oy, dropable);
|
||||
_x11_dnd_dropable_handle(dropable, x - ox, y - oy, EINA_TRUE);
|
||||
// CCCCCCC: call dnd exit on last obj if obj != last
|
||||
// CCCCCCC: call drop position on obj
|
||||
_x11_dropable_all_set(pos->win, x, y, EINA_TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
ecore_x_dnd_send_status(EINA_FALSE, EINA_FALSE, rect, pos->action);
|
||||
cnp_debug("dnd position not in obj\n");
|
||||
_x11_dnd_dropable_handle(dropable_old, 0, 0, EINA_FALSE);
|
||||
// CCCCCCC: call dnd exit on last obj
|
||||
_x11_dropable_all_set(pos->win, x, y, EINA_TRUE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ecore_x_dnd_send_status(EINA_FALSE, EINA_FALSE, rect, pos->action);
|
||||
}
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_x11_dnd_leave(void *data __UNUSED__, int etype __UNUSED__, void *ev)
|
||||
{
|
||||
Ecore_X_Event_Xdnd_Leave *leave = ev;
|
||||
Dropable *dropable;
|
||||
|
||||
dropable = _x11_dropable_find(leave->win);
|
||||
if (dropable)
|
||||
{
|
||||
cnp_debug("Leave %x\n", leave->win);
|
||||
_x11_dnd_dropable_handle(dropable, 0, 0, EINA_FALSE);
|
||||
_x11_dropable_all_set(leave->win, 0, 0, EINA_FALSE);
|
||||
// CCCCCCC: call dnd exit on last obj if there was one
|
||||
}
|
||||
// leave->win leave->source
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_x11_dnd_drop(void *data __UNUSED__, int etype __UNUSED__, void *ev)
|
||||
{
|
||||
struct _Ecore_X_Event_Xdnd_Drop *drop;
|
||||
Ecore_X_Event_Xdnd_Drop *drop;
|
||||
Dropable *dropable;
|
||||
Eina_List *l;
|
||||
Ecore_Evas *ee;
|
||||
Ecore_X_Window xwin;
|
||||
Elm_Selection_Data ddata;
|
||||
int x, y, w, h;
|
||||
Evas_Coord x = 0, y = 0;
|
||||
int i, j;
|
||||
|
||||
drop = ev;
|
||||
|
||||
cnp_debug("drops %p (%d)\n", drops, eina_list_count(drops));
|
||||
|
||||
// check we still have something to drop
|
||||
if (!drops) return EINA_TRUE;
|
||||
|
||||
/* Find any widget in our window; then work out geometry rel to our window */
|
||||
for (l = drops; l; l = l->next)
|
||||
{
|
||||
dropable = l->data;
|
||||
xwin = _x11_elm_widget_xwin_get(dropable->obj);
|
||||
if (xwin == drop->win) break;
|
||||
}
|
||||
/* didn't find a window */
|
||||
if (!l) return EINA_TRUE;
|
||||
if (!(dropable = _x11_dropable_find(drop->win))) return EINA_TRUE;
|
||||
|
||||
/* Calculate real (widget relative) position */
|
||||
// - window position
|
||||
// - widget position
|
||||
ee = ecore_evas_ecore_evas_get(evas_object_evas_get(dropable->obj));
|
||||
ecore_evas_geometry_get(ee, &x, &y, NULL, NULL);
|
||||
savedtypes.x = drop->position.x - x;
|
||||
savedtypes.y = drop->position.y - y;
|
||||
savedtypes.x = drop->position.x;
|
||||
savedtypes.y = drop->position.y;
|
||||
_x11_dropable_coords_adjust(dropable, &savedtypes.x, &savedtypes.y);
|
||||
|
||||
cnp_debug("Drop position is %d,%d\n", savedtypes.x, savedtypes.y);
|
||||
|
||||
for (; l; l = l->next)
|
||||
{
|
||||
dropable = l->data;
|
||||
if (xwin == drop->win)
|
||||
{
|
||||
if (evas_object_visible_get(dropable->obj))
|
||||
{
|
||||
evas_object_geometry_get(dropable->obj, &x, &y, &w, &h);
|
||||
if ((savedtypes.x >= x) && (savedtypes.y >= y) &&
|
||||
(savedtypes.x < x + w) && (savedtypes.y < y + h))
|
||||
break; /* found! */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!l) return EINA_TRUE; /* didn't find one */
|
||||
dropable = _x11_dropable_geom_find(drop->win, savedtypes.x, savedtypes.y);
|
||||
if (!dropable) return EINA_TRUE; /* didn't find one */
|
||||
|
||||
evas_object_geometry_get(dropable->obj, &x, &y, NULL, NULL);
|
||||
savedtypes.x -= x;
|
||||
|
@ -1122,7 +1287,7 @@ _x11_dnd_drop(void *data __UNUSED__, int etype __UNUSED__, void *ev)
|
|||
|
||||
found:
|
||||
cnp_debug("Found a target we'd like: %s\n", _x11_atoms[i].name);
|
||||
cnp_debug("0x%x\n",xwin);
|
||||
cnp_debug("0x%x\n", drop->win);
|
||||
|
||||
if (i == CNP_ATOM_text_urilist)
|
||||
{
|
||||
|
@ -1185,46 +1350,22 @@ found:
|
|||
}
|
||||
|
||||
cnp_debug("doing a request then\n");
|
||||
_x11_selections[ELM_SEL_TYPE_XDND].xwin = xwin;
|
||||
_x11_selections[ELM_SEL_TYPE_XDND].xwin = drop->win;
|
||||
_x11_selections[ELM_SEL_TYPE_XDND].requestwidget = dropable->obj;
|
||||
_x11_selections[ELM_SEL_TYPE_XDND].requestformat = ELM_SEL_FORMAT_MARKUP;
|
||||
_x11_selections[ELM_SEL_TYPE_XDND].active = EINA_TRUE;
|
||||
|
||||
ecore_x_selection_xdnd_request(xwin, _x11_atoms[i].name);
|
||||
ecore_x_selection_xdnd_request(drop->win, _x11_atoms[i].name);
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_x11_dnd_position(void *data __UNUSED__, int etype __UNUSED__, void *ev)
|
||||
{
|
||||
struct _Ecore_X_Event_Xdnd_Position *pos = ev;
|
||||
Ecore_X_Rectangle rect;
|
||||
|
||||
/* Need to send a status back */
|
||||
/* FIXME: Should check I can drop here */
|
||||
/* FIXME: Should highlight widget */
|
||||
rect.x = pos->position.x - 5;
|
||||
rect.y = pos->position.y - 5;
|
||||
rect.width = 10;
|
||||
rect.height = 10;
|
||||
ecore_x_dnd_send_status(EINA_TRUE, EINA_FALSE, rect, pos->action);
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* When dragging this is callback response from the destination.
|
||||
* The important thing we care about: Can we drop; thus update cursor
|
||||
* appropriately.
|
||||
*/
|
||||
static Eina_Bool
|
||||
_x11_dnd_status(void *data __UNUSED__, int etype __UNUSED__, void *ev)
|
||||
{
|
||||
struct _Ecore_X_Event_Xdnd_Status *status = ev;
|
||||
|
||||
if (!status) return EINA_TRUE;
|
||||
Ecore_X_Event_Xdnd_Status *status = ev;
|
||||
|
||||
/* Only thing we care about: will accept */
|
||||
if (status->will_accept) cnp_debug("Will accept\n");
|
||||
if ((status) && (status->will_accept)) cnp_debug("Will accept\n");
|
||||
/* Won't accept */
|
||||
else cnp_debug("Won't accept accept\n");
|
||||
return EINA_TRUE;
|
||||
|
@ -1249,7 +1390,12 @@ _x11_drag_mouse_up(void *data, int etype __UNUSED__, void *event)
|
|||
ecore_event_handler_del(handler_up);
|
||||
handler_up = NULL;
|
||||
}
|
||||
ecore_x_dnd_drop();
|
||||
if (handler_status)
|
||||
{
|
||||
ecore_event_handler_del(handler_status);
|
||||
handler_status = NULL;
|
||||
}
|
||||
ecore_x_dnd_self_drop();
|
||||
|
||||
cnp_debug("mouse up, xwin=%#llx\n", (unsigned long long)xwin);
|
||||
|
||||
|
@ -1317,6 +1463,7 @@ _x11_elm_cnp_init(void)
|
|||
ecore_x_selection_converter_atom_add
|
||||
(_x11_atoms[i].atom, _x11_atoms[i].converter);
|
||||
}
|
||||
//XXX delete handlers?
|
||||
ecore_event_handler_add(ECORE_X_EVENT_SELECTION_CLEAR, _x11_selection_clear, NULL);
|
||||
ecore_event_handler_add(ECORE_X_EVENT_SELECTION_NOTIFY, _x11_selection_notify, NULL);
|
||||
return EINA_TRUE;
|
||||
|
@ -1419,7 +1566,8 @@ _x11_elm_object_cnp_selection_clear(Evas_Object *obj, Elm_Sel_Type selection)
|
|||
|
||||
static Eina_Bool
|
||||
_x11_elm_cnp_selection_get(Evas_Object *obj, Elm_Sel_Type selection,
|
||||
Elm_Sel_Format format, Elm_Drop_Cb datacb, void *udata)
|
||||
Elm_Sel_Format format, Elm_Drop_Cb datacb,
|
||||
void *udata)
|
||||
{
|
||||
Ecore_X_Window xwin = _x11_elm_widget_xwin_get(obj);
|
||||
X11_Cnp_Selection *sel;
|
||||
|
@ -1448,6 +1596,9 @@ _x11_elm_cnp_selection_get(Evas_Object *obj, Elm_Sel_Type selection,
|
|||
|
||||
static Eina_Bool
|
||||
_x11_elm_drop_target_add(Evas_Object *obj, Elm_Sel_Format format,
|
||||
Elm_Drag_State entercb, void *enterdata,
|
||||
Elm_Drag_State leavecb, void *leavedata,
|
||||
Elm_Drag_Pos poscb, void *posdata,
|
||||
Elm_Drop_Cb dropcb, void *cbdata)
|
||||
{
|
||||
Dropable *drop;
|
||||
|
@ -1485,6 +1636,12 @@ _x11_elm_drop_target_add(Evas_Object *obj, Elm_Sel_Format format,
|
|||
free(drop);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
drop->entercb = entercb;
|
||||
drop->enterdata = enterdata;
|
||||
drop->leavecb = leavecb;
|
||||
drop->leavedata = leavedata;
|
||||
drop->poscb = poscb;
|
||||
drop->posdata = posdata;
|
||||
drop->dropcb = dropcb;
|
||||
drop->cbdata = cbdata;
|
||||
drop->types = format;
|
||||
|
@ -1504,6 +1661,8 @@ _x11_elm_drop_target_add(Evas_Object *obj, Elm_Sel_Format format,
|
|||
cnp_debug("Adding drop target calls xwin=%#llx\n", (unsigned long long)xwin);
|
||||
handler_enter = ecore_event_handler_add(ECORE_X_EVENT_XDND_ENTER,
|
||||
_x11_dnd_enter, NULL);
|
||||
handler_leave = ecore_event_handler_add(ECORE_X_EVENT_XDND_LEAVE,
|
||||
_x11_dnd_leave, NULL);
|
||||
handler_pos = ecore_event_handler_add(ECORE_X_EVENT_XDND_POSITION,
|
||||
_x11_dnd_position, NULL);
|
||||
handler_drop = ecore_event_handler_add(ECORE_X_EVENT_XDND_DROP,
|
||||
|
@ -1554,9 +1713,29 @@ _x11_elm_drop_target_del(Evas_Object *obj)
|
|||
}
|
||||
if (!have_drops) ecore_x_dnd_aware_set(xwin, EINA_FALSE);
|
||||
|
||||
if (!drops)
|
||||
{
|
||||
if (handler_pos)
|
||||
{
|
||||
ecore_event_handler_del(handler_pos);
|
||||
handler_pos = NULL;
|
||||
}
|
||||
if (handler_drop)
|
||||
{
|
||||
ecore_event_handler_del(handler_drop);
|
||||
handler_drop = NULL;
|
||||
}
|
||||
if (handler_enter)
|
||||
{
|
||||
ecore_event_handler_del(handler_enter);
|
||||
handler_enter = NULL;
|
||||
}
|
||||
if (handler_leave)
|
||||
{
|
||||
ecore_event_handler_del(handler_leave);
|
||||
handler_leave = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (savedtypes.imgfile) free(savedtypes.imgfile);
|
||||
savedtypes.imgfile = NULL;
|
||||
|
@ -1566,10 +1745,8 @@ _x11_elm_drop_target_del(Evas_Object *obj)
|
|||
|
||||
static Eina_Bool
|
||||
_x11_elm_drag_start(Evas_Object *obj, Elm_Sel_Format format, const char *data,
|
||||
Evas_Object *(*createicon) (void *data, Evas_Object *win, Evas_Coord *xoff, Evas_Coord *yoff),
|
||||
void *createdata,
|
||||
void (*dragdone) (void *data, Evas_Object *obj),
|
||||
void *donecbdata)
|
||||
Elm_Drag_Icon_Create_Cb createicon, void *createdata,
|
||||
Elm_Drag_State dragdone, void *donecbdata)
|
||||
{
|
||||
Ecore_X_Window xwin = _x11_elm_widget_xwin_get(obj);
|
||||
X11_Cnp_Selection *sel;
|
||||
|
@ -1602,15 +1779,14 @@ _x11_elm_drag_start(Evas_Object *obj, Elm_Sel_Format format, const char *data,
|
|||
/* TODO BUG: should increase dnd-awareness, in case it's drop target as well. See _x11_drag_mouse_up() */
|
||||
ecore_x_dnd_aware_set(xwin, EINA_TRUE);
|
||||
ecore_x_dnd_callback_pos_update_set(_x11_drag_move, NULL);
|
||||
ecore_x_dnd_begin(xwin, (unsigned char *)&xdnd, sizeof(Elm_Sel_Type));
|
||||
ecore_x_dnd_self_begin(xwin, (unsigned char *)&xdnd, sizeof(Elm_Sel_Type));
|
||||
ecore_x_pointer_grab(xwin);
|
||||
handler_up = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP, _x11_drag_mouse_up,
|
||||
handler_up = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP,
|
||||
_x11_drag_mouse_up,
|
||||
(void *)(long)xwin);
|
||||
// evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_UP,
|
||||
// _x11_drag_mouse_up, (void *)(long)xwin);
|
||||
handler_status = ecore_event_handler_add(ECORE_X_EVENT_XDND_STATUS,
|
||||
_x11_dnd_status, NULL);
|
||||
dragwin = elm_win_add(NULL, "Elm Drag Object", ELM_WIN_UTILITY);
|
||||
dragwin = elm_win_add(NULL, "Elm-Drag", ELM_WIN_UTILITY);
|
||||
elm_win_alpha_set(dragwin, EINA_TRUE);
|
||||
elm_win_override_set(dragwin, EINA_TRUE);
|
||||
|
||||
|
@ -1846,7 +2022,11 @@ static Eina_Bool _local_elm_cnp_selection_set(Evas_Object *obj __UNUSED__, Elm_
|
|||
static void _local_elm_cnp_selection_loss_callback_set(Evas_Object *obj __UNUSED__, Elm_Sel_Type selection __UNUSED__, Elm_Selection_Loss_Cb func __UNUSED__, const void *data __UNUSED__);
|
||||
static Eina_Bool _local_elm_object_cnp_selection_clear(Evas_Object *obj __UNUSED__, Elm_Sel_Type selection);
|
||||
static Eina_Bool _local_elm_cnp_selection_get(Evas_Object *obj, Elm_Sel_Type selection, Elm_Sel_Format format __UNUSED__, Elm_Drop_Cb datacb, void *udata);
|
||||
static Eina_Bool _local_elm_drop_target_add(Evas_Object *obj __UNUSED__, Elm_Sel_Format format __UNUSED__, Elm_Drop_Cb dropcb __UNUSED__, void *cbdata __UNUSED__);
|
||||
static Eina_Bool _local_elm_drop_target_add(Evas_Object *obj __UNUSED__, Elm_Sel_Format format __UNUSED__,
|
||||
Elm_Drag_State entercb __UNUSED__, void *enterdata __UNUSED__,
|
||||
Elm_Drag_State leavecb __UNUSED__, void *leavedata __UNUSED__,
|
||||
Elm_Drag_Pos poscb __UNUSED__, void *posdata __UNUSED__,
|
||||
Elm_Drop_Cb dropcb __UNUSED__, void *cbdata __UNUSED__);
|
||||
static Eina_Bool _local_elm_drop_target_del(Evas_Object *obj __UNUSED__);
|
||||
static Eina_Bool _local_elm_drag_start(Evas_Object *obj __UNUSED__, Elm_Sel_Format format __UNUSED__, const char *data __UNUSED__, Evas_Object *(*createicon) (void *data, Evas_Object *win, Evas_Coord *xoff, Evas_Coord *yoff) __UNUSED__, void *createdata __UNUSED__, void (*dragdone) (void *data, Evas_Object *) __UNUSED__, void *donecbdata __UNUSED__);
|
||||
static Eina_Bool _local_elm_selection_selection_has_owner(Evas_Object *obj __UNUSED__);
|
||||
|
@ -1941,6 +2121,12 @@ _local_elm_cnp_selection_get(Evas_Object *obj,
|
|||
static Eina_Bool
|
||||
_local_elm_drop_target_add(Evas_Object *obj __UNUSED__,
|
||||
Elm_Sel_Format format __UNUSED__,
|
||||
Elm_Drag_State entercb __UNUSED__,
|
||||
void *enterdata __UNUSED__,
|
||||
Elm_Drag_State leavecb __UNUSED__,
|
||||
void *leavedata __UNUSED__,
|
||||
Elm_Drag_Pos poscb __UNUSED__,
|
||||
void *posdata __UNUSED__,
|
||||
Elm_Drop_Cb dropcb __UNUSED__,
|
||||
void *cbdata __UNUSED__)
|
||||
{
|
||||
|
@ -1961,9 +2147,9 @@ static Eina_Bool
|
|||
_local_elm_drag_start(Evas_Object *obj __UNUSED__,
|
||||
Elm_Sel_Format format __UNUSED__,
|
||||
const char *data __UNUSED__,
|
||||
Evas_Object *(*createicon) (void *data, Evas_Object *win, Evas_Coord *xoff, Evas_Coord *yoff) __UNUSED__,
|
||||
Elm_Drag_Icon_Create_Cb createicon __UNUSED__,
|
||||
void *createdata __UNUSED__,
|
||||
void (*dragdone) (void *data, Evas_Object *obj) __UNUSED__,
|
||||
Elm_Drag_State dragdone __UNUSED__,
|
||||
void *donecbdata __UNUSED__)
|
||||
{
|
||||
// XXX: implement me
|
||||
|
@ -2173,14 +2359,21 @@ elm_cnp_selection_get(Evas_Object *obj, Elm_Sel_Type selection,
|
|||
*/
|
||||
EAPI Eina_Bool
|
||||
elm_drop_target_add(Evas_Object *obj, Elm_Sel_Format format,
|
||||
Elm_Drag_State entercb, void *enterdata,
|
||||
Elm_Drag_State leavecb, void *leavedata,
|
||||
Elm_Drag_Pos poscb, void *posdata,
|
||||
Elm_Drop_Cb dropcb, void *cbdata)
|
||||
{
|
||||
if (!_elm_cnp_init_count) _elm_cnp_init();
|
||||
#ifdef HAVE_ELEMENTARY_X
|
||||
if (_x11_elm_widget_xwin_get(obj))
|
||||
return _x11_elm_drop_target_add(obj, format, dropcb, cbdata);
|
||||
return _x11_elm_drop_target_add(obj, format, entercb, enterdata,
|
||||
leavecb, leavedata, poscb, posdata,
|
||||
dropcb, cbdata);
|
||||
#endif
|
||||
return _local_elm_drop_target_add(obj, format, dropcb, cbdata);
|
||||
return _local_elm_drop_target_add(obj, format, entercb, enterdata,
|
||||
leavecb, leavedata, poscb, posdata,
|
||||
dropcb, cbdata);
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
|
@ -2196,10 +2389,8 @@ elm_drop_target_del(Evas_Object *obj)
|
|||
|
||||
EAPI Eina_Bool
|
||||
elm_drag_start(Evas_Object *obj, Elm_Sel_Format format, const char *data,
|
||||
Evas_Object *(*createicon) (void *data, Evas_Object *win, Evas_Coord *xoff, Evas_Coord *yoff),
|
||||
void *createdata,
|
||||
void (*dragdone) (void *data, Evas_Object *obj),
|
||||
void *donecbdata)
|
||||
Elm_Drag_Icon_Create_Cb createicon, void *createdata,
|
||||
Elm_Drag_State dragdone, void *donecbdata)
|
||||
{
|
||||
if (!_elm_cnp_init_count) _elm_cnp_init();
|
||||
#ifdef HAVE_ELEMENTARY_X
|
||||
|
|
|
@ -106,6 +106,37 @@ typedef Eina_Bool (*Elm_Drop_Cb)(void *data, Evas_Object *obj, Elm_Selection_Dat
|
|||
*/
|
||||
typedef void (*Elm_Selection_Loss_Cb)(void *data, Elm_Sel_Type selection);
|
||||
|
||||
/**
|
||||
* Callback called to create a drag icon object
|
||||
*
|
||||
* @param data Application specific data
|
||||
* @param win The window to create the objects relative to
|
||||
* @param xoff A return coordinate for the X offset at which to place the drag icon object relative to the source drag object
|
||||
* @param yoff A return coordinate for the Y offset at which to place the drag icon object relative to the source drag object
|
||||
* @return An object to fill the drag window with or NULL if not needed
|
||||
* @since 1.8
|
||||
*/
|
||||
typedef Evas_Object *(*Elm_Drag_Icon_Create_Cb) (void *data, Evas_Object *win, Evas_Coord *xoff, Evas_Coord *yoff);
|
||||
|
||||
/**
|
||||
* Callback called when a drag is finished, enters, or leaves an object
|
||||
*
|
||||
* @param data Application specific data
|
||||
* @param obj The object where the drag started
|
||||
* @since 1.8
|
||||
*/
|
||||
typedef void (*Elm_Drag_State) (void *data, Evas_Object *obj);
|
||||
|
||||
/**
|
||||
* Callback called when a drag is ober an object, and gives object-lrelative coordinates
|
||||
*
|
||||
* @param data Application specific data
|
||||
* @param obj The object where the drag started
|
||||
* @param x The X coordinate relative to the top-left of the object
|
||||
* @param y The Y coordinate relative to the top-left of the object
|
||||
* @since 1.8
|
||||
*/
|
||||
typedef void (*Elm_Drag_Pos) (void *data, Evas_Object *obj, Evas_Coord x, Evas_Coord y);
|
||||
|
||||
/**
|
||||
* @brief Set copy data for a widget.
|
||||
|
@ -199,6 +230,61 @@ EAPI Eina_Bool elm_object_cnp_selection_clear(Evas_Object *obj,
|
|||
*/
|
||||
EAPI void elm_cnp_selection_loss_callback_set(Evas_Object *obj, Elm_Sel_Type selection, Elm_Selection_Loss_Cb func, const void *data);
|
||||
|
||||
/**
|
||||
* @brief Set the given object as a target for drops for drag-and-drop
|
||||
*
|
||||
* @param obj The target object
|
||||
* @param format The formats supported for dropping
|
||||
* @param entercb The function to call when the object is entered with a drag
|
||||
* @param enterdata The application data to pass to enterdata
|
||||
* @param leavecb The function to call when the object is left with a drag
|
||||
* @param leavedata The application data to pass to leavedata
|
||||
* @param poscb The function to call when the object has a drag over it
|
||||
* @param posdata The application data to pass to posdata
|
||||
* @param dropcb The function to call when a drop has occurred
|
||||
* @param cbdata The application data to pass to dropcb
|
||||
* @return Returns EINA_TRUE, if successful, or EINA_FALSE if not.
|
||||
*
|
||||
* @ingroup CopyPaste
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
EAPI Eina_Bool elm_drop_target_add(Evas_Object *obj, Elm_Sel_Format format,
|
||||
Elm_Drag_State entercb, void *enterdata,
|
||||
Elm_Drag_State leavecb, void *leavedata,
|
||||
Elm_Drag_Pos poscb, void *posdata,
|
||||
Elm_Drop_Cb dropcb, void *cbdata);
|
||||
|
||||
/**
|
||||
* @brief Deletes the drop target status of an object
|
||||
*
|
||||
* @param obj The target object
|
||||
* @return Returns EINA_TRUE, if successful, or EINA_FALSE if not.
|
||||
*
|
||||
* @ingroup CopyPaste
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
EAPI Eina_Bool elm_drop_target_del(Evas_Object *obj);
|
||||
|
||||
/**
|
||||
* @brief Begins a drag given a source object
|
||||
*
|
||||
* @param obj The source object
|
||||
* @param format The drag formats supported by the data
|
||||
* @param data The drag data itself (a string)
|
||||
* @param createicon Function to call to create a drag object, or NULL if not wanted
|
||||
* @param createdata Application data passed to @p createicon
|
||||
* @param dragdone Function to call when drag is done
|
||||
* @param donecbdata Application data to pass to @p dragdone
|
||||
* @return Returns EINA_TRUE, if successful, or EINA_FALSE if not.
|
||||
*
|
||||
* @ingroup CopyPaste
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
EAPI Eina_Bool elm_drag_start(Evas_Object *obj, Elm_Sel_Format format, const char *data, Elm_Drag_Icon_Create_Cb createicon, void *createdata, Elm_Drag_State dragdone, void *donecbdata);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
|
|
@ -2900,11 +2900,13 @@ _elm_entry_smart_add(Eo *obj, void *_pd, va_list *list EINA_UNUSED)
|
|||
ecore_event_handler_add
|
||||
(ECORE_X_EVENT_SELECTION_CLEAR, _event_selection_clear, obj);
|
||||
}
|
||||
|
||||
#endif
|
||||
elm_drop_target_add
|
||||
(obj, ELM_SEL_FORMAT_MARKUP | ELM_SEL_FORMAT_IMAGE,
|
||||
NULL, NULL,
|
||||
NULL, NULL,
|
||||
NULL, NULL,
|
||||
_drag_drop_cb, NULL);
|
||||
#endif
|
||||
|
||||
entries = eina_list_prepend(entries, obj);
|
||||
|
||||
|
@ -3201,16 +3203,16 @@ _password_set(Eo *obj, void *_pd, va_list *list)
|
|||
{
|
||||
sd->single_line = EINA_TRUE;
|
||||
sd->line_wrap = ELM_WRAP_NONE;
|
||||
#ifdef HAVE_ELEMENTARY_X
|
||||
elm_drop_target_del(obj);
|
||||
#endif
|
||||
_entry_selection_callbacks_unregister(obj);
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef HAVE_ELEMENTARY_X
|
||||
elm_drop_target_add(obj, ELM_SEL_FORMAT_MARKUP, _drag_drop_cb, NULL);
|
||||
#endif
|
||||
elm_drop_target_add(obj, ELM_SEL_FORMAT_MARKUP,
|
||||
NULL, NULL,
|
||||
NULL, NULL,
|
||||
NULL, NULL,
|
||||
_drag_drop_cb, NULL);
|
||||
_entry_selection_callbacks_register(obj);
|
||||
}
|
||||
|
||||
|
@ -3461,12 +3463,14 @@ _editable_set(Eo *obj, void *_pd, va_list *list)
|
|||
sd->editable = editable;
|
||||
eo_do(obj, elm_wdg_theme(NULL));
|
||||
|
||||
#ifdef HAVE_ELEMENTARY_X
|
||||
if (editable)
|
||||
elm_drop_target_add(obj, ELM_SEL_FORMAT_MARKUP, _drag_drop_cb, NULL);
|
||||
elm_drop_target_add(obj, ELM_SEL_FORMAT_MARKUP,
|
||||
NULL, NULL,
|
||||
NULL, NULL,
|
||||
NULL, NULL,
|
||||
_drag_drop_cb, NULL);
|
||||
else
|
||||
elm_drop_target_del(obj);
|
||||
#endif
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
|
@ -4432,9 +4436,11 @@ _cnp_mode_set(Eo *obj, void *_pd, va_list *list)
|
|||
format = ELM_SEL_FORMAT_TEXT;
|
||||
else if (cnp_mode == ELM_CNP_MODE_MARKUP)
|
||||
format |= ELM_SEL_FORMAT_IMAGE;
|
||||
#ifdef HAVE_ELEMENTARY_X
|
||||
elm_drop_target_add(obj, format, _drag_drop_cb, NULL);
|
||||
#endif
|
||||
elm_drop_target_add(obj, format,
|
||||
NULL, NULL,
|
||||
NULL, NULL,
|
||||
NULL, NULL,
|
||||
_drag_drop_cb, NULL);
|
||||
}
|
||||
|
||||
EAPI Elm_Cnp_Mode
|
||||
|
|
|
@ -1045,7 +1045,11 @@ _elm_image_smart_editable_set(Eo *obj, void *_pd, va_list *list)
|
|||
|
||||
if (sd->edit)
|
||||
elm_drop_target_add
|
||||
(obj, ELM_SEL_FORMAT_IMAGE, _elm_image_drag_n_drop_cb, parent);
|
||||
(obj, ELM_SEL_FORMAT_IMAGE,
|
||||
NULL, NULL,
|
||||
NULL, NULL,
|
||||
NULL, NULL,
|
||||
_elm_image_drag_n_drop_cb, parent);
|
||||
else
|
||||
elm_drop_target_del(obj);
|
||||
}
|
||||
|
|
|
@ -840,7 +840,11 @@ _editable_set(Eo *obj, void *_pd, va_list *list)
|
|||
|
||||
sd->edit = edit;
|
||||
if (sd->edit)
|
||||
elm_drop_target_add(obj, ELM_SEL_FORMAT_IMAGE, _elm_thumb_dnd_cb, obj);
|
||||
elm_drop_target_add(obj, ELM_SEL_FORMAT_IMAGE,
|
||||
NULL, NULL,
|
||||
NULL, NULL,
|
||||
NULL, NULL,
|
||||
_elm_thumb_dnd_cb, obj);
|
||||
else
|
||||
elm_drop_target_del(obj);
|
||||
}
|
||||
|
|
|
@ -998,25 +998,6 @@ EAPI void elm_widget_tree_dot_dump(const Evas_Object *top, FILE *out
|
|||
* parsing script skips it */
|
||||
#define ELM_INTERNAL_SMART_SUBCLASS_NEW EVAS_SMART_SUBCLASS_NEW
|
||||
|
||||
/**
|
||||
* The drag and drop API.
|
||||
* Currently experimental, and will change when it does dynamic type
|
||||
* addition RSN.
|
||||
*
|
||||
* Here so applications can start to use it, if they ask elm nicely.
|
||||
*
|
||||
* And yes, elm_widget, should probably be elm_experimental...
|
||||
* Complaints about this code should go to /dev/null, or failing that nash.
|
||||
*/
|
||||
EAPI Eina_Bool elm_drop_target_add(Evas_Object *widget, Elm_Sel_Format format,
|
||||
Elm_Drop_Cb dropcb, void *cbdata);
|
||||
EAPI Eina_Bool elm_drop_target_del(Evas_Object *widget);
|
||||
EAPI Eina_Bool elm_drag_start(Evas_Object *obj, Elm_Sel_Format format,
|
||||
const char *data,
|
||||
Evas_Object *(*createicon) (void *data, Evas_Object *win, Evas_Coord *xoff, Evas_Coord *yoff),
|
||||
void *createdata,
|
||||
void (*dragdone) (void *data, Evas_Object *obj),
|
||||
void *donecbdata);
|
||||
EAPI Eina_Bool elm_selection_selection_has_owner(Evas_Object *obj);
|
||||
|
||||
#define ELM_OBJ_WIDGET_CLASS elm_widget_class_get()
|
||||
|
|
Loading…
Reference in New Issue