e_dnd: Add hooks for drag start and end 21/296421/1
authorJunseok Kim <juns.kim@samsung.com>
Wed, 12 Jul 2023 10:23:45 +0000 (19:23 +0900)
committerTizen Window System <tizen.windowsystem@gmail.com>
Thu, 27 Jul 2023 07:15:32 +0000 (16:15 +0900)
Change-Id: I05de28281118c8615739bd4b8a5d5374be9932bd

src/bin/e_dnd.c
src/bin/e_dnd.h

index 2db95fd..3a38aee 100644 (file)
@@ -1,7 +1,15 @@
 #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);
 
@@ -15,9 +23,83 @@ static Eina_List *_event_handlers = NULL;
 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)
 {
@@ -155,6 +237,8 @@ e_drag_resize(E_Drag *drag, int w, int h)
 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);
 }
 
@@ -171,6 +255,8 @@ _e_drag_end(E_Drag *drag)
 {
    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;
index 127b1e9..8a45d76 100644 (file)
@@ -1,6 +1,7 @@
 #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
@@ -8,6 +9,16 @@ typedef struct _E_Drag            E_Drag;
 
 #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;
@@ -44,5 +55,9 @@ EINTERN void            e_drag_resize(E_Drag *drag, int w, int h);
 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