Elementary: DnD work
- Genlist default animation test functional - Some callbacks are still missing
This commit is contained in:
parent
40d5c4250a
commit
87ee22d559
|
@ -1,5 +1,6 @@
|
|||
from efl.elementary.enums cimport Elm_Sel_Type, Elm_Sel_Format, \
|
||||
Elm_Xdnd_Action
|
||||
from efl.utils.conversions cimport python_list_objects_to_eina_list
|
||||
|
||||
cdef extern from "Elementary.h":
|
||||
struct _Elm_Selection_Data:
|
||||
|
@ -78,7 +79,7 @@ cdef class SelectionData(object):
|
|||
property data:
|
||||
def __get__(self):
|
||||
# TODO: void *
|
||||
return None
|
||||
return <const_char *>self.sel_data.data
|
||||
|
||||
property len:
|
||||
""":type: size_t"""
|
||||
|
@ -103,6 +104,8 @@ cdef Eina_Bool py_elm_drop_cb(void *data, Evas_Object *obj, Elm_Selection_Data *
|
|||
:param ev: struct holding information about selected data
|
||||
|
||||
"""
|
||||
print("in drop_cb")
|
||||
assert data != NULL, "data is NULL"
|
||||
cdef:
|
||||
SelectionData sd = SelectionData.__new__(SelectionData)
|
||||
bint ret
|
||||
|
@ -146,10 +149,10 @@ cdef Elm_Object_Item *py_elm_xy_item_get_cb(Evas_Object *obj, Evas_Coord x, Evas
|
|||
|
||||
if xpos1 is not None:
|
||||
xpos2 = xpos1
|
||||
xposret = &xpos2
|
||||
xposret[0] = xpos2
|
||||
if ypos1 is not None:
|
||||
ypos2 = ypos1
|
||||
yposret = &ypos2
|
||||
yposret[0] = ypos2
|
||||
|
||||
return it.item
|
||||
|
||||
|
@ -181,6 +184,40 @@ cdef Evas_Object *py_elm_drag_icon_create_cb(
|
|||
|
||||
"""
|
||||
print("in drag_icon_create_cb")
|
||||
assert data != NULL, "data is NULL"
|
||||
|
||||
cdef:
|
||||
evasObject win1 = object_from_instance(win)
|
||||
evasObject icon
|
||||
object xoff1 = None, yoff1 = None
|
||||
Evas_Coord xoff2, yoff2
|
||||
|
||||
createicon, createdata = <object>data
|
||||
|
||||
if xoff != NULL:
|
||||
xoff1 = xoff[0]
|
||||
if yoff != NULL:
|
||||
yoff1 = yoff[0]
|
||||
|
||||
try:
|
||||
ret = createicon(win1, xoff1, yoff1, createdata)
|
||||
except:
|
||||
traceback.print_exc()
|
||||
return NULL
|
||||
|
||||
if ret is None:
|
||||
return NULL
|
||||
|
||||
icon, xoff1, yoff1 = ret
|
||||
|
||||
if xoff1 is not None:
|
||||
xoff2 = xoff1
|
||||
xoff[0] = xoff2
|
||||
if yoff1 is not None:
|
||||
yoff2 = yoff1
|
||||
yoff[0] = yoff2
|
||||
|
||||
return icon.obj
|
||||
|
||||
cdef void py_elm_drag_state_cb(void *data, Evas_Object *obj) with gil:
|
||||
"""Callback called when a drag is finished, enters, or leaves an object
|
||||
|
@ -192,6 +229,28 @@ cdef void py_elm_drag_state_cb(void *data, Evas_Object *obj) with gil:
|
|||
"""
|
||||
print("in drag_state_cb")
|
||||
|
||||
cdef void py_elm_drag_done_cb(void *data, Evas_Object *obj, Eina_Bool accepted) with gil:
|
||||
"""Callback called when a drag is finished.
|
||||
|
||||
@param data Application specific data
|
||||
@param obj The object where the drag started
|
||||
@param accepted TRUE if the droppped-data is accepted on drop
|
||||
:since: 1.8
|
||||
|
||||
"""
|
||||
print("in drag_done_cb")
|
||||
assert data != NULL, "data is NULL"
|
||||
|
||||
cdef:
|
||||
evasObject o = object_from_instance(obj)
|
||||
|
||||
donecb, donedata = <object>data
|
||||
|
||||
try:
|
||||
donecb(o, <bint>accepted, donedata)
|
||||
except:
|
||||
traceback.print_exc()
|
||||
|
||||
cdef void py_elm_drag_accept_cb(void *data, Evas_Object *obj, Eina_Bool doaccept) with gil:
|
||||
"""Callback called when a drag is responded to with an accept or deny
|
||||
|
||||
|
@ -215,7 +274,17 @@ cdef void py_elm_drag_pos_cb(void *data, Evas_Object *obj,
|
|||
|
||||
"""
|
||||
print("in drag_pos_cb")
|
||||
assert data != NULL, "data is NULL"
|
||||
|
||||
cdef:
|
||||
evasObject o = object_from_instance(obj)
|
||||
|
||||
dragpos, dragdata = <object>data
|
||||
|
||||
try:
|
||||
dragpos(o, x, y, action, dragdata)
|
||||
except:
|
||||
traceback.print_exc()
|
||||
|
||||
cdef void py_elm_drag_item_container_pos(
|
||||
void *data, Evas_Object *cont, Elm_Object_Item *it,
|
||||
|
@ -254,7 +323,26 @@ cdef Eina_Bool py_elm_drop_item_container_cb(
|
|||
|
||||
"""
|
||||
print("in drop_item_container_cb")
|
||||
assert obj != NULL, "obj is NULL"
|
||||
|
||||
cdef:
|
||||
evasObject o = object_from_instance(obj)
|
||||
ObjectItem item = _object_item_to_python(it)
|
||||
SelectionData evdata = SelectionData.__new__(SelectionData)
|
||||
object cbdata = None
|
||||
|
||||
evdata.sel_data = ev
|
||||
|
||||
cb = o.data["drop_item_container_cb"]
|
||||
|
||||
if data != NULL:
|
||||
cbdata = <object>data
|
||||
|
||||
try:
|
||||
ret = cb(o, item, evdata, xposret, yposret, cbdata)
|
||||
except:
|
||||
traceback.print_exc()
|
||||
return 0
|
||||
|
||||
cdef class DragUserInfo(object):
|
||||
"""
|
||||
|
@ -277,8 +365,21 @@ cdef class DragUserInfo(object):
|
|||
@param donecbdata Application data to pass to @p dragdone (output)
|
||||
|
||||
"""
|
||||
cdef:
|
||||
public Elm_Sel_Format format
|
||||
public Elm_Xdnd_Action action
|
||||
public list icons
|
||||
public object createicon, createdata, dragpos, dragdata
|
||||
public object acceptcb, acceptdata, dragdone, donecbdata
|
||||
const_char *_data
|
||||
|
||||
cdef Elm_Drag_User_Info *info
|
||||
property data:
|
||||
def __get__(self):
|
||||
return _ctouni(self._data)
|
||||
|
||||
def __set__(self, value):
|
||||
if isinstance(value, unicode): value = PyUnicode_AsUTF8String(value)
|
||||
self._data = value
|
||||
|
||||
# Elm_Sel_Format format;
|
||||
# const char *data;
|
||||
|
@ -306,3 +407,44 @@ cdef Eina_Bool py_elm_item_container_data_get_cb(
|
|||
|
||||
"""
|
||||
print("in item_container_data_get_cb")
|
||||
|
||||
cdef:
|
||||
DragUserInfo ret
|
||||
evasObject o = object_from_instance(obj)
|
||||
ObjectItem item = _object_item_to_python(it)
|
||||
|
||||
try:
|
||||
ret = <DragUserInfo?>o.data["item_container_data_get_cb"](o, item)
|
||||
except:
|
||||
traceback.print_exc()
|
||||
return 0
|
||||
|
||||
if ret is not None:
|
||||
print("populating info")
|
||||
info.format = ret.format
|
||||
info.data = ret._data
|
||||
info.icons = python_list_objects_to_eina_list(ret.icons)
|
||||
if ret.createicon is not None:
|
||||
info.createicon = py_elm_drag_icon_create_cb
|
||||
createdata = (ret.createicon, ret.createdata)
|
||||
Py_INCREF(createdata)
|
||||
info.createdata = <void *>createdata
|
||||
if ret.dragpos is not None:
|
||||
info.dragpos = py_elm_drag_pos_cb
|
||||
dragdata = (ret.dragpos, ret.dragdata)
|
||||
Py_INCREF(dragdata)
|
||||
info.dragdata = <void *>dragdata
|
||||
if ret.acceptcb is not None:
|
||||
info.acceptcb = py_elm_drag_accept_cb
|
||||
acceptdata = (ret.acceptcb, ret.acceptdata)
|
||||
Py_INCREF(acceptdata)
|
||||
info.acceptdata = <void *>acceptdata
|
||||
if ret.dragdone is not None:
|
||||
info.dragdone =py_elm_drag_done_cb
|
||||
donecbdata = (ret.dragdone, ret.donecbdata)
|
||||
Py_INCREF(donecbdata)
|
||||
info.donecbdata = <void *>donecbdata
|
||||
return 1
|
||||
else:
|
||||
print("ret is None")
|
||||
return 0
|
||||
|
|
|
@ -694,6 +694,8 @@ cdef class Genlist(Object):
|
|||
raise TypeError("itemgetcb must be callable.")
|
||||
self.data["xy_item_get_cb"] = itemgetcb
|
||||
|
||||
self.data["item_container_data_get_cb"] = data_get
|
||||
|
||||
if not elm_drag_item_container_add(self.obj,
|
||||
tm_to_anim,
|
||||
tm_to_drag,
|
||||
|
@ -742,17 +744,20 @@ cdef class Genlist(Object):
|
|||
raise TypeError("itemgetcb must be callable.")
|
||||
self.data["xy_item_get_cb"] = itemgetcb
|
||||
|
||||
self.data["drag_item_container_pos"] = poscb
|
||||
self.data["drop_item_container_cb"] = dropcb
|
||||
|
||||
if not elm_drop_item_container_add(self.obj,
|
||||
format,
|
||||
<Elm_Xy_Item_Get_Cb>py_elm_xy_item_get_cb if itemgetcb is not None else NULL,
|
||||
<Elm_Drag_State>py_elm_drag_state_cb if entercb is not None else NULL,
|
||||
<void *>enterdata,
|
||||
<void *>enterdata if enterdata is not None else NULL,
|
||||
<Elm_Drag_State>py_elm_drag_state_cb if leavecb is not None else NULL,
|
||||
<void *>leavedata,
|
||||
<void *>leavedata if leavedata is not None else NULL,
|
||||
<Elm_Drag_Item_Container_Pos>py_elm_drag_item_container_pos if poscb is not None else NULL,
|
||||
<void *>posdata,
|
||||
<void *>posdata if posdata is not None else NULL,
|
||||
<Elm_Drop_Item_Container_Cb>py_elm_drop_item_container_cb if dropcb is not None else NULL,
|
||||
<void *>cbdata):
|
||||
<void *>cbdata if cbdata is not None else NULL):
|
||||
raise RuntimeError
|
||||
|
||||
def drop_item_container_del(self):
|
||||
|
|
|
@ -7,7 +7,7 @@ from efl.elementary.box import Box
|
|||
from efl.elementary.window import StandardWindow
|
||||
from efl.elementary.icon import Icon
|
||||
from efl.elementary.genlist import Genlist, GenlistItemClass, \
|
||||
ELM_SEL_FORMAT_TARGETS, ELM_GENLIST_ITEM_NONE
|
||||
ELM_SEL_FORMAT_TARGETS, ELM_GENLIST_ITEM_NONE, DragUserInfo
|
||||
|
||||
img = (
|
||||
"panel_01.jpg",
|
||||
|
@ -39,19 +39,12 @@ img = (
|
|||
DRAG_TIMEOUT = 0.3
|
||||
ANIM_TIME = 0.5
|
||||
|
||||
def item_ptr_cmp(d1, d2):
|
||||
return (d1 - d2)
|
||||
|
||||
#static Elm_Genlist_Item_Class *itc1
|
||||
#static Elm_Gengrid_Item_Class *gic
|
||||
|
||||
|
||||
class DndItemClass(GenlistItemClass):
|
||||
def text_get(self, obj, part, data, *args):
|
||||
return data
|
||||
|
||||
def content_get(self, obj, part, data, *args):
|
||||
if not part == "elm.swallow.icon":
|
||||
if part == "elm.swallow.icon":
|
||||
icon = Icon(obj)
|
||||
icon.file = data
|
||||
icon.size_hint_aspect = evas.EVAS_ASPECT_CONTROL_VERTICAL, 1, 1
|
||||
|
@ -59,8 +52,10 @@ class DndItemClass(GenlistItemClass):
|
|||
return icon
|
||||
return None
|
||||
|
||||
itc1 = DndItemClass()
|
||||
|
||||
def win_del(obj, data):
|
||||
#print("<%s> <%d> will del <%p>\n", __func__, __LINE__, data)
|
||||
print("will del <%s>" % data)
|
||||
data.drop_item_container_del()
|
||||
data.drag_item_container_del()
|
||||
|
||||
|
@ -73,12 +68,11 @@ def win_del(obj, data):
|
|||
|
||||
def gl_item_getcb(gl, x, y):
|
||||
# This function returns pointer to item under (x,y) coords
|
||||
#print("<%s> <%d> obj=<%p>\n", __func__, __LINE__, gl)
|
||||
gli, yposret = gl.at_xy_item_get(x, y)
|
||||
if gli is not None:
|
||||
print("over <%s>, gli=<%s> yposret %i\n" % (gli.part_text_get("elm.text"), gli, yposret))
|
||||
print("over <%s>, gli=<%s> yposret %i" % (gli.part_text_get("elm.text"), gli, yposret))
|
||||
else:
|
||||
print("over none, yposret %i\n", yposret)
|
||||
print("over none, yposret %i" % yposret)
|
||||
return gli, None, yposret
|
||||
|
||||
# def grid_item_getcb(obj, x, y, int *xposret, int *yposret):
|
||||
|
@ -92,43 +86,34 @@ def gl_item_getcb(gl, x, y):
|
|||
# print("over none, xposret %i yposret %i\n", *xposret, *yposret)
|
||||
# return item
|
||||
|
||||
def gl_dropcb(data, obj, it,
|
||||
ev, # Elm_Selection_Data *
|
||||
xposret, yposret):
|
||||
def gl_dropcb(obj, it, ev, xposret, yposret, data):
|
||||
# This function is called when data is dropped on the genlist
|
||||
#print("<%s> <%d> str=<%s>\n", __func__, __LINE__, (char *) ev->data)
|
||||
if ev.data is None:
|
||||
return False
|
||||
|
||||
p = ev.data
|
||||
p = strchr(p, '#')
|
||||
while p is not None:
|
||||
p += 1
|
||||
p2 = strchr(p, '#')
|
||||
if p2 is not None:
|
||||
p2 = '\0'
|
||||
print("Item %s\n", p)
|
||||
|
||||
wh0rdlist = p.split("#")
|
||||
|
||||
wh0rdlist.pop(0)
|
||||
wh0rdlist.pop()
|
||||
|
||||
for wh0rd in wh0rdlist:
|
||||
print("Item %s" % wh0rd)
|
||||
|
||||
if yposret == -1:
|
||||
obj.item_insert_before(itc1, p, before=it,
|
||||
flags=ELM_GENLIST_ITEM_NONE)
|
||||
obj.item_insert_before(itc1, wh0rd, before_item=it, flags=ELM_GENLIST_ITEM_NONE)
|
||||
elif yposret == 0 or yposret == 1:
|
||||
if not it:
|
||||
it = obj.last_item
|
||||
|
||||
if it:
|
||||
it = obj.item_insert_after(itc1, p, None, it,
|
||||
ELM_GENLIST_ITEM_NONE)
|
||||
it = obj.item_insert_after(itc1, wh0rd, after_item=it, flags=ELM_GENLIST_ITEM_NONE)
|
||||
else:
|
||||
it = obj.item_append(itc1, p, None,
|
||||
ELM_GENLIST_ITEM_NONE)
|
||||
it = obj.item_append(itc1, wh0rd, flags=ELM_GENLIST_ITEM_NONE)
|
||||
else:
|
||||
return False
|
||||
|
||||
p = p2
|
||||
|
||||
else:
|
||||
p = None
|
||||
|
||||
return True
|
||||
|
||||
# def grid_dropcb(data, obj, it, Elm_Selection_Data *ev, int xposret, int yposret):
|
||||
|
@ -284,19 +269,19 @@ def gl_dropcb(data, obj, it,
|
|||
# # END - Handling drag start animation
|
||||
|
||||
def gl_dragdone(obj, doaccept, data):
|
||||
#print("<%s> <%d> data=<%p> doaccept=<%d>\n", __func__, __LINE__, data, doaccept)
|
||||
|
||||
if doaccept:
|
||||
# Remove items dragged out (accepted by target)
|
||||
for it in data:
|
||||
it.delete()
|
||||
|
||||
def gl_createicon(data, win, xoff, yoff):
|
||||
def gl_createicon(win, xoff, yoff, data):
|
||||
#print("<%s> <%d>\n", __func__, __LINE__)
|
||||
it = data
|
||||
o = it.part_content_get("elm.swallow.icon")
|
||||
|
||||
if o is not None:
|
||||
if o is None:
|
||||
return
|
||||
|
||||
w = h = 30
|
||||
|
||||
f, g = o.file
|
||||
|
@ -313,15 +298,14 @@ def gl_createicon(data, win, xoff, yoff):
|
|||
icon.size_hint_align = evas.EVAS_HINT_FILL, evas.EVAS_HINT_FILL
|
||||
icon.size_hint_weight = evas.EVAS_HINT_EXPAND, evas.EVAS_HINT_EXPAND
|
||||
|
||||
if xoff is not None and yoff is not None:
|
||||
if (xoff is not None) and (yoff is not None):
|
||||
icon.move(xoff, yoff)
|
||||
icon.resize(w, h)
|
||||
|
||||
return icon
|
||||
return icon, xoff, yoff
|
||||
|
||||
def gl_icons_get(data):
|
||||
# Start icons animation before actually drag-starts
|
||||
#print("<%s> <%d>\n", __func__, __LINE__)
|
||||
gl = data
|
||||
|
||||
yposret = 0
|
||||
|
@ -329,18 +313,17 @@ def gl_icons_get(data):
|
|||
icons = []
|
||||
|
||||
xm, ym = gl.evas.pointer_canvas_xy
|
||||
items = gl.selected_items
|
||||
gli = gl.at_xy_item_get(xm, ym, yposret)
|
||||
items = list(gl.selected_items)
|
||||
gli, yposret = gl.at_xy_item_get(xm, ym)
|
||||
|
||||
if gli is not None:
|
||||
# Add the item mouse is over to the list if NOT seleced
|
||||
p = eina_list_search_unsorted(items, _item_ptr_cmp, gli)
|
||||
if p is not None:
|
||||
items = eina_list_append(items, gli)
|
||||
if not gli in items:
|
||||
items.append(gli)
|
||||
|
||||
for gli in items:
|
||||
for it in items:
|
||||
# Now add icons to animation window
|
||||
o = gli.part_content_get("elm.swallow.icon")
|
||||
o = it.part_content_get("elm.swallow.icon")
|
||||
|
||||
if o is not None:
|
||||
f, g = o.file
|
||||
|
@ -356,22 +339,19 @@ def gl_icons_get(data):
|
|||
|
||||
icons.append(ic)
|
||||
|
||||
eina_list_free(items)
|
||||
return icons
|
||||
|
||||
def gl_get_drag_data(gl, it, items):
|
||||
def gl_get_drag_data(gl, it):
|
||||
# Construct a string of dragged info, user frees returned string
|
||||
drag_data = None
|
||||
#print("<%s> <%d>\n", __func__, __LINE__)
|
||||
|
||||
items = gl.selected_items
|
||||
items = list(gl.selected_items)
|
||||
if it is not None:
|
||||
# Add the item mouse is over to the list if NOT seleced
|
||||
p = eina_list_search_unsorted(items, _item_ptr_cmp, it)
|
||||
if p is None:
|
||||
items = eina_list_append(items, it)
|
||||
if not it in items:
|
||||
items.append(it)
|
||||
|
||||
if items:
|
||||
if items is not None:
|
||||
# Now we can actually compose string to send and start dragging
|
||||
drag_data = "file://"
|
||||
|
||||
|
@ -383,9 +363,9 @@ def gl_get_drag_data(gl, it, items):
|
|||
|
||||
drag_data += "#"
|
||||
|
||||
#print("<%s> <%d> Sending <%s>\n", __func__, __LINE__, drag_data)
|
||||
print("Sending <%s>" % drag_data)
|
||||
|
||||
return drag_data
|
||||
return drag_data, items
|
||||
|
||||
# def grid_get_drag_data(gg, it, Eina_List **items):
|
||||
# # Construct a string of dragged info, user frees returned string
|
||||
|
@ -432,26 +412,25 @@ def gl_get_drag_data(gl, it, items):
|
|||
|
||||
# return drag_data
|
||||
|
||||
def gl_dnd_default_anim_data_getcb(gl, it,
|
||||
info # Elm_Drag_User_Info *
|
||||
):
|
||||
def gl_dnd_default_anim_data_getcb(gl, it):
|
||||
# This called before starting to drag, mouse-down was on it
|
||||
info = DragUserInfo()
|
||||
info.format = ELM_SEL_FORMAT_TARGETS
|
||||
info.createicon = _gl_createicon
|
||||
info.createicon = gl_createicon
|
||||
info.createdata = it
|
||||
info.icons = _gl_icons_get(obj)
|
||||
info.dragdone = _gl_dragdone
|
||||
info.icons = gl_icons_get(gl)
|
||||
info.dragdone = gl_dragdone
|
||||
|
||||
# Now, collect data to send for drop from ALL selected items
|
||||
# Save list pointer to remove items after drop and free list on done
|
||||
info.data = _gl_get_drag_data(obj, it, info.donecbdata)
|
||||
#print("%s - data = %s\n", __FUNCTION__, info->data)
|
||||
info.data, info.donecbdata = gl_get_drag_data(gl, it)
|
||||
|
||||
info.acceptdata = info.donecbdata
|
||||
|
||||
if info.data is not None:
|
||||
return True
|
||||
return info
|
||||
else:
|
||||
return False
|
||||
return
|
||||
|
||||
# def gl_data_getcb(gl, it,
|
||||
# Elm_Drag_User_Info *info):
|
||||
|
@ -563,7 +542,7 @@ def dnd_genlist_default_anim_clicked(*args):
|
|||
bxx.pack_end(gl)
|
||||
gl.show()
|
||||
|
||||
itc1 = DndItemClass()
|
||||
#itc1 = DndItemClass()
|
||||
|
||||
for i in range (20):
|
||||
gl.item_append(itc1, "images/{0}".format(img[i % 9]), flags=ELM_GENLIST_ITEM_NONE)
|
||||
|
|
Loading…
Reference in New Issue