DnD: cancel feature during drag
authorDaniel Zaoui <daniel.zaoui@samsung.com>
Thu, 28 Nov 2013 14:06:46 +0000 (16:06 +0200)
committerDaniel Zaoui <daniel.zaoui@samsung.com>
Mon, 9 Dec 2013 07:32:43 +0000 (09:32 +0200)
This can be tested by running "Features DnD" test. Enable the 5s cancel
timeout, drag an item and wait for the cancellation.

legacy/elementary/src/bin/test_dnd.c
legacy/elementary/src/lib/elm_cnp.c
legacy/elementary/src/lib/elm_cnp.h

index 093383e..d3fddf0 100644 (file)
@@ -40,6 +40,9 @@ typedef struct _drag_anim_st drag_anim_st;
 #define DRAG_TIMEOUT 0.3
 #define ANIM_TIME 0.5
 
+static Eina_Bool _5s_cancel = EINA_FALSE;
+static Ecore_Timer *_5s_timeout = NULL;
+
 static int
 _item_ptr_cmp(const void *d1, const void *d2)
 {
@@ -378,6 +381,12 @@ _gl_dragdone(void *data, Evas_Object *obj EINA_UNUSED, Eina_Bool doaccept)
    Elm_Object_Item *it;
    Eina_List *l;
 
+   if (_5s_cancel)
+     {
+        ecore_timer_del(_5s_timeout);
+        _5s_timeout = NULL;
+     }
+
    if (doaccept)
      {  /* Remove items dragged out (accepted by target) */
         EINA_LIST_FOREACH(data, l, it)
@@ -388,6 +397,15 @@ _gl_dragdone(void *data, Evas_Object *obj EINA_UNUSED, Eina_Bool doaccept)
    return;
 }
 
+static Eina_Bool
+_5s_timeout_gone(void *data)
+{
+   printf("Cancel DnD\n");
+   Evas_Object *obj = data;
+   elm_drag_cancel(obj);
+   return ECORE_CALLBACK_CANCEL;
+}
+
 static Evas_Object *
 _gl_createicon(void *data, Evas_Object *win, Evas_Coord *xoff, Evas_Coord *yoff)
 {
@@ -658,6 +676,14 @@ _grid_icons_get(void *data)
    return icons;
 }
 
+static void
+_gl_dragstart(void *data EINA_UNUSED, Evas_Object *obj)
+{
+   printf("<%s> <%d>\n", __func__, __LINE__);
+   if (_5s_cancel)
+      _5s_timeout = ecore_timer_add(5.0, _5s_timeout_gone, obj);
+}
+
 static Eina_Bool
 _grid_data_getcb(Evas_Object *obj,  /* The genlist object */
       Elm_Object_Item *it,
@@ -666,6 +692,7 @@ _grid_data_getcb(Evas_Object *obj,  /* The genlist object */
    info->format = ELM_SEL_FORMAT_TARGETS;
    info->createicon = _gl_createicon;
    info->createdata = it;
+   info->dragstart = _gl_dragstart;
    info->icons = _grid_icons_get(obj);
    info->dragdone = _gl_dragdone;
 
@@ -959,6 +986,12 @@ static Eina_Bool _drop_bg_change_cb(void *data EINA_UNUSED, Evas_Object *obj, El
    return EINA_TRUE;
 }
 
+static void
+_5s_cancel_ck_changed(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
+{
+   _5s_cancel = elm_check_state_get(obj);
+}
+
 void
 test_dnd_multi_features(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
 {
@@ -1019,6 +1052,15 @@ test_dnd_multi_features(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, vo
         evas_object_show(vert_box);
         elm_drop_target_add(vert_box, ELM_SEL_FORMAT_TARGETS, NULL, NULL, NULL, NULL, NULL, NULL, _drop_box_button_new_cb, win);
 
+        _5s_cancel = EINA_FALSE;
+        Evas_Object *ck = elm_check_add(vert_box);
+        elm_object_style_set(ck, "toggle");
+        elm_object_text_set(ck, "Cancel after 5s:");
+        elm_check_state_set(ck, _5s_cancel);
+        evas_object_smart_callback_add(ck, "changed", _5s_cancel_ck_changed, NULL);
+        elm_box_pack_end(vert_box, ck);
+        evas_object_show(ck);
+
         ic = elm_icon_add(win);
         snprintf(buf, sizeof(buf), "%s/images/logo_small.png", elm_app_data_dir_get());
         elm_image_file_set(ic, buf, NULL);
index 16a3cd6..e54548b 100644 (file)
@@ -4245,3 +4245,30 @@ elm_drag_item_container_add(Evas_Object *obj, double anim_tm, double tm_to_drag,
 }
 /* END   - Support elm containers for Drag */
 /* END   - Support elm containers for Drag and Drop */
+
+EAPI Eina_Bool
+elm_drag_cancel(Evas_Object *obj)
+{
+#ifdef HAVE_ELEMENTARY_X
+   Ecore_X_Window xwin = _x11_elm_widget_xwin_get(obj);
+   if (xwin)
+     {
+        ecore_x_pointer_ungrab();
+        ELM_SAFE_FREE(handler_up, ecore_event_handler_del);
+        ELM_SAFE_FREE(handler_status, ecore_event_handler_del);
+        ecore_x_dnd_abort(xwin);
+     }
+#endif
+#ifdef HAVE_ELEMENTARY_WAYLAND
+/* Have to complete here.
+ * if (elm_win_wl_window_get(obj)) ... */
+#endif
+
+   ELM_SAFE_FREE(dragwin, evas_object_del);
+   dragdonecb = NULL;
+   dragacceptcb = NULL;
+   dragposcb = NULL;
+   dragwidget = NULL;
+   doaccept = EINA_FALSE;
+   return EINA_TRUE;
+}
index a24deb9..14b36a9 100644 (file)
@@ -367,6 +367,21 @@ EAPI Eina_Bool elm_drag_start(Evas_Object *obj, Elm_Sel_Format format,
                               Elm_Drag_Pos dragpos, void *dragdata,
                               Elm_Drag_Accept acceptcb, void *acceptdata,
                               Elm_Drag_State dragdone, void *donecbdata);
+
+/**
+ * @brief Cancels the current drag operation
+ *
+ * It can only be initiated from the source window.
+ *
+ * @param obj The source of the current drag.
+ * @return Returns EINA_TRUE, if successful, or EINA_FALSE if not.
+ *
+ * @ingroup CopyPaste
+ *
+ * @since 1.9
+ */
+EAPI Eina_Bool elm_drag_cancel(Evas_Object *obj);
+
 /**
  * @brief Changes the current drag action
  *