#include "e.h"
-/* local subsystem functions */
+struct _E_Drag_Hook
+{
+ EINA_INLIST;
+ E_Drag_Hook_Point hookpoint;
+ E_Drag_Hook_Cb func;
+ void *data;
+ unsigned char delete_me : 1;
+};
+/* local subsystem functions */
static void _e_drag_end(E_Drag *drag);
static void _e_drag_free(E_Drag *drag);
static Eina_List *_zone_event_handlers = NULL;
static Ecore_Window _drag_win = 0;
-
static E_Drag *_drag_current = NULL;
+
+static int _e_drag_hooks_delete = 0;
+static int _e_drag_hooks_walking = 0;
+static Eina_Inlist *_e_drag_hooks[] =
+{
+ [E_DRAG_HOOK_DRAG_START] = NULL,
+ [E_DRAG_HOOK_DRAG_END] = NULL,
+};
+
+
+EINTERN E_Drag_Hook *
+e_drag_hook_add(E_Drag_Hook_Point hookpoint, E_Drag_Hook_Cb func, const void *data)
+{
+ E_Drag_Hook *hook;
+
+ EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_DRAG_HOOK_LAST, NULL);
+ hook = E_NEW(E_Drag_Hook, 1);
+ if (!hook) return NULL;
+
+ hook->hookpoint = hookpoint;
+ hook->func = func;
+ hook->data = (void*)data;
+ _e_drag_hooks[hookpoint] = eina_inlist_append(_e_drag_hooks[hookpoint], EINA_INLIST_GET(hook));
+ return hook;
+}
+
+EINTERN void
+e_drag_hook_del(E_Drag_Hook *hook)
+{
+ hook->delete_me = 1;
+ if (_e_drag_hooks_walking == 0)
+ {
+ _e_drag_hooks[hook->hookpoint] = eina_inlist_remove(_e_drag_hooks[hook->hookpoint], EINA_INLIST_GET(hook));
+ free(hook);
+ }
+ else
+ _e_drag_hooks_delete++;
+}
+
+static void
+_e_drag_hooks_clean(void)
+{
+ Eina_Inlist *l;
+ E_Drag_Hook *hook;
+ unsigned int x;
+
+ for (x = 0; x < E_DRAG_HOOK_LAST; x++)
+ EINA_INLIST_FOREACH_SAFE(_e_drag_hooks[x], l, hook)
+ {
+ if (!hook->delete_me) continue;
+ _e_drag_hooks[x] = eina_inlist_remove(_e_drag_hooks[x], EINA_INLIST_GET(hook));
+ free(hook);
+ }
+}
+
+static Eina_Bool
+_e_drag_hook_call(E_Drag_Hook_Point hookpoint, E_Drag *drag)
+{
+ E_Drag_Hook *hook;
+
+ e_object_ref(E_OBJECT(drag));
+ _e_drag_hooks_walking++;
+ EINA_INLIST_FOREACH(_e_drag_hooks[hookpoint], hook)
+ {
+ if (hook->delete_me) continue;
+ hook->func(hook->data, drag);
+ if (e_object_is_del(E_OBJECT(drag)))
+ break;
+ }
+ _e_drag_hooks_walking--;
+ if ((_e_drag_hooks_walking == 0) && (_e_drag_hooks_delete > 0))
+ _e_drag_hooks_clean();
+ return !!e_object_unref(E_OBJECT(drag));
+}
+
static int
_e_drag_finalize(E_Drag *drag, int x, int y)
{
EINTERN int
e_drag_start(E_Drag *drag, int x, int y)
{
+ _e_drag_hook_call(E_DRAG_HOOK_DRAG_START, drag);
+
return _e_drag_finalize(drag, x, y);
}
{
evas_object_hide(drag->comp_object);
+ _e_drag_hook_call(E_DRAG_HOOK_DRAG_END, drag);
+
if (drag->cb.finished)
drag->cb.finished(drag);
drag->cb.finished = NULL;
#ifdef E_TYPEDEFS
-typedef struct _E_Drag E_Drag;
+typedef struct _E_Drag E_Drag;
+typedef struct _E_Drag_Hook E_Drag_Hook;
#else
#ifndef E_DND_H
#define E_DRAG_TYPE 0xE0b0100f
+typedef void (*E_Drag_Hook_Cb)(void *data, E_Drag *drag);
+
+typedef enum _E_Drag_Hook_Point
+{
+ E_DRAG_HOOK_DRAG_START,
+ E_DRAG_HOOK_DRAG_END,
+ E_DRAG_HOOK_LAST,
+} E_Drag_Hook_Point;
+
+
struct _E_Drag
{
E_Object e_obj_inherit;
EINTERN int e_drag_start(E_Drag *drag, int x, int y);
EINTERN void e_drag_end(E_Drag *drag);
+
+EINTERN E_Drag_Hook * e_drag_hook_add(E_Drag_Hook_Point hookpoint, E_Drag_Hook_Cb func, const void *data);
+EINTERN void e_drag_hook_del(E_Drag_Hook *hook);
+
#endif
#endif