yakov pushed a commit to branch master. http://git.enlightenment.org/tools/erigo.git/commit/?id=ee2cce27069ab0998e57fa55e9772aa09d8204de
commit ee2cce27069ab0998e57fa55e9772aa09d8204de Author: Yakov Goldberg <[email protected]> Date: Tue Aug 25 19:22:04 2015 +0300 Start adding DRAG from objtree --- src/bin/gui/dnd.c | 36 +++++++++++++++--- src/bin/gui/dnd.h | 9 +++++ src/bin/gui/editor.c | 101 +++++++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 124 insertions(+), 22 deletions(-) diff --git a/src/bin/gui/dnd.c b/src/bin/gui/dnd.c index 01cbe9f..ac005c6 100644 --- a/src/bin/gui/dnd.c +++ b/src/bin/gui/dnd.c @@ -19,7 +19,7 @@ typedef struct Eo *drag_window_obj_wref; const Gui_Widget *wdg; /* let's think about it as about DnD data. */ - void (*_drag_start_cb)(const Gui_Widget *wdg, const Eo *obj); + void (*_drag_start_post_cb)(const Gui_Widget *wdg, const Eo *obj); } Drag_Info; static Ecore_Timer *_drag_factory_timer = NULL; @@ -461,9 +461,9 @@ _drag_start(void *data) _dragaccept, NULL, _dragstate, NULL); - if (di->_drag_start_cb) + if (di->_drag_start_post_cb) { - di->_drag_start_cb(di->wdg, di->obj); + di->_drag_start_post_cb(di->wdg, di->obj); } return ECORE_CALLBACK_CANCEL; } @@ -537,7 +537,7 @@ drag_add(Eo *obj, const char *image_path, const char *data) } /* Function to start dragging, when mouse down/up are handled outside. - * Dragging widgets. */ + * Dragging widgets on canvas */ void drag_start(Eo *obj, const char *data, const Gui_Widget *wdg, void (*cb)(const Gui_Widget *, const Eo *)) { @@ -546,12 +546,24 @@ drag_start(Eo *obj, const char *data, const Gui_Widget *wdg, void (*cb)(const Gu di->data = data; di->obj = obj; di->wdg = wdg; - di->_drag_start_cb = cb; + di->_drag_start_post_cb = cb; _dnd_info.drag_info = di; _drag_start(di); } +/* Function to start dragging, when mouse down/up are handled outside. + * Dragging widgets on canvas */ +void +drag_item_start(const char *data, const Gui_Widget *wdg) +{ + Drag_Info *di = calloc(1, sizeof(Drag_Info)); + di->image_path = NULL; + di->data = data; + di->wdg = wdg; + _dnd_info.drag_info = di; +} + /* Function to stop dragging, when mouse down/up are handled outside. * Dragging widgets. */ void @@ -640,17 +652,29 @@ drop_target_main_wdg_set(Gui_Widget *wdg, Eo *obj, void drop_item_container_set(Eo *obj, Elm_Xy_Item_Get_Cb itemgetcb, Elm_Drop_Item_Container_Cb dropcb, void *dropdata) { - elm_drop_item_container_add(obj, ELM_SEL_FORMAT_TARGETS, itemgetcb, + elm_drop_item_container_add(obj, ELM_SEL_FORMAT_TEXT, itemgetcb, _dropenter, NULL, _dropleave, NULL, NULL, NULL, dropcb, dropdata); } void +drag_item_container_set(Eo *obj, double anim_tm, double tm_to_drag, Elm_Xy_Item_Get_Cb itemgetcb, Elm_Item_Container_Data_Get_Cb data_get) +{ + elm_drag_item_container_add(obj, anim_tm, tm_to_drag, itemgetcb, data_get); +} + +void drop_item_container_del(Eo *obj) { elm_drop_item_container_del(obj); } void +drag_item_container_del(Eo *obj) +{ + elm_drag_item_container_del(obj); +} + +void drop_target_wdg_del(Gui_Widget *wdg, Eo *obj) { Target_Info *ti = NULL; diff --git a/src/bin/gui/dnd.h b/src/bin/gui/dnd.h index 79470a7..804d62e 100644 --- a/src/bin/gui/dnd.h +++ b/src/bin/gui/dnd.h @@ -9,6 +9,9 @@ void drag_start(Eo *obj, const char *data, const Gui_Widget *wdg, void (*cb)(const Gui_Widget *, const Eo *)); void +drag_item_start(const char *data, const Gui_Widget *wdg); + +void drag_stop(); void @@ -34,6 +37,12 @@ drop_item_container_set(Eo *obj, Elm_Xy_Item_Get_Cb itemgetcb, Elm_Drop_Item_Con void drop_item_container_del(Eo *obj); +void +drag_item_container_set(Eo *obj, double anim_tm, double tm_to_drag, Elm_Xy_Item_Get_Cb itemgetcb, Elm_Item_Container_Data_Get_Cb data_get); + +void +drag_item_container_del(Eo *obj); + const char* dnd_drag_data_get(); diff --git a/src/bin/gui/editor.c b/src/bin/gui/editor.c index 884c088..9e84de1 100644 --- a/src/bin/gui/editor.c +++ b/src/bin/gui/editor.c @@ -57,7 +57,7 @@ typedef struct int pointer_x; int pointer_y; } -DnD_Info; +DnD_Main_Obj_Info; /* Function to call in the end of undo/redo in order to update view. * Update is made according to head memento. */ @@ -579,7 +579,7 @@ _drag_widget_iterate(Gui_Widget **drag_candidate, const Gui_Session *session, Ev } void -_drag_start_cb(const Gui_Widget *wdg, const Eo *_wdg_eo); +_drag_start_post_cb(const Gui_Widget *wdg, const Eo *_wdg_eo); static Ecore_Timer *_drag_timer_start = NULL; static Eina_Bool drag_started = EINA_FALSE; @@ -609,7 +609,7 @@ _drag_widget_start(void *data) const Gui_Session *session = gui_context_editor_session_get(wdg_context_get(wdg)); Eo *wdg_eo = session_eo_get(session, wdg); - drag_start(wdg_eo, EDITOR_DRAG_DATA, wdg, _drag_start_cb); + drag_start(wdg_eo, EDITOR_DRAG_DATA, wdg, _drag_start_post_cb); drag_started = EINA_TRUE; _drag_timer_start = NULL; return ECORE_CALLBACK_CANCEL; @@ -1221,9 +1221,9 @@ _frame_mouse_up(void *data EINA_UNUSED, Eo *obj, const Eo_Event_Description *des if (!dnd_is_in_drop_target()) { /* Check if dragged object is visible. - * If not, means that _drag_start_cb was called, so need to reload main wdg. */ + * If not, means that _drag_start_post_cb was called, so need to reload main wdg. */ Eo *canvas = egui_layout_gui_get()->main_win->canvas_scroller; - DnD_Info *di = eo_do_ret(canvas, di, eo_key_data_get(EDITOR_DND_DATA)); + DnD_Main_Obj_Info *di = eo_do_ret(canvas, di, eo_key_data_get(EDITOR_DND_DATA)); const Gui_Widget *drag_widget = dnd_drag_wdg_get(); if (!drag_widget) return EO_CALLBACK_CONTINUE; @@ -1661,7 +1661,7 @@ _drop_target_main_wdg_enter(void *data, Evas_Object *obj) Eo *canvas_drop_target = obj; Eo *canvas = NULL; Gui_Widget *wdg = data; - DnD_Info *di = NULL; + DnD_Main_Obj_Info *di = NULL; /* If wdg == NULL, then canvas is a drop target or we have a error.*/ if (wdg) { @@ -1712,7 +1712,7 @@ _drop_target_main_wdg_leave(void *data, Evas_Object *obj) { Gui_Widget *wdg = data; Eo *canvas_drop_target = obj; - DnD_Info *di = NULL; + DnD_Main_Obj_Info *di = NULL; if (wdg) { di = wdg_data_get(wdg, EDITOR_DND_DATA); @@ -1747,7 +1747,7 @@ _drop_target_enter(void *data, Evas_Object *obj EINA_UNUSED) /* Draw border around drop target. */ _wdg_border_draw(wdg, EINA_TRUE, BORDER_DROP_TARGET); Eo *wdg_eo = NULL; - DnD_Info *di = wdg_data_get(wdg_main_wdg_get(wdg), EDITOR_DND_DATA); + DnD_Main_Obj_Info *di = wdg_data_get(wdg_main_wdg_get(wdg), EDITOR_DND_DATA); if (!IS_MAIN(wdg)) { const Gui_Session *session = gui_context_editor_session_get(wdg_context_get(wdg)); @@ -1785,7 +1785,7 @@ _drop_target_leave(void *data, Evas_Object *obj EINA_UNUSED) { Gui_Widget *wdg = data; _wdg_border_draw(wdg, EINA_FALSE, BORDER_DROP_TARGET); - DnD_Info *di = wdg_data_get(wdg_main_wdg_get(wdg), EDITOR_DND_DATA); + DnD_Main_Obj_Info *di = wdg_data_get(wdg_main_wdg_get(wdg), EDITOR_DND_DATA); Eo *wdg_eo = NULL; const Gui_Context *ctx = wdg_context_get(wdg); const Gui_Session *session = gui_context_editor_session_get(ctx); @@ -1858,7 +1858,7 @@ _editor_factory_wdg_create(const char *class_name, const Gui_Widget *focused_wdg static Eina_Bool _drop_target_drop(Gui_Widget *wdg, Eo *canvas_drop_target, const char *drag_data, Eina_Bool dropped_to_objtree) { - DnD_Info *di = NULL; + DnD_Main_Obj_Info *di = NULL; const Gui_Widget *new_wdg = NULL; int drop_to_wdg = NO_DROP; @@ -2328,6 +2328,74 @@ _objtree_drop_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, Elm_Objec return EINA_TRUE; } +static Eina_Bool +_3s_timeout_gone(void *data) +{ + elm_drag_cancel(data); + return ECORE_CALLBACK_CANCEL; +} + +static void +_gl_dragstart(void *data EINA_UNUSED, Evas_Object *obj) +{ + ecore_timer_add(3.0, _3s_timeout_gone, obj); +} + +static Evas_Object * +_gl_createicon(void *data, Evas_Object *win, Evas_Coord *xoff, Evas_Coord *yoff) +{ + Evas_Object *icon = NULL; + Evas_Object *o = elm_object_item_part_content_get(data, "elm.swallow.icon"); + + if (o) + { + int xm, ym, w = 30, h = 30; + const char *f; + const char *gr; + elm_image_file_get(o, &f, &gr); + evas_pointer_canvas_xy_get(evas_object_evas_get(o), &xm, &ym); + if (xoff) *xoff = xm - (w/2); + if (yoff) *yoff = ym - (h/2); + icon = elm_icon_add(win); + elm_image_file_set(icon, f, gr); + evas_object_size_hint_align_set(icon, + EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_size_hint_weight_set(icon, + EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + if (xoff && yoff) evas_object_move(icon, *xoff, *yoff); + evas_object_resize(icon, w, h); + } + + return icon; +} + +static Eina_Bool +_objtree_data_getcb(Evas_Object *obj EINA_UNUSED, /* The genlist object */ + Elm_Object_Item *it, + Elm_Drag_User_Info *info) +{ + /* This called before starting to drag, mouse-down was on it */ + info->format = ELM_SEL_FORMAT_TEXT; + info->createicon = _gl_createicon; + info->createdata = it; + info->dragstart = _gl_dragstart; + info->icons = NULL; + info->dragdone = NULL; + + /* 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 = strdup(EDITOR_DRAG_DATA); + + Gui_Widget *wdg = elm_object_item_data_get(it); + drag_item_start(EDITOR_DRAG_DATA, wdg); + + if (info->data) + return EINA_TRUE; + else + return EINA_FALSE; +} + + static void _table_cell_segment_get(int x, int y, int cell_w, int cell_h, int *_part_x, int *_part_y) { @@ -2350,7 +2418,7 @@ _drop_target_pos(void *data, Eo *obj, Evas_Coord x, Evas_Coord y, Elm_Xdnd_Actio { Eo *canvas_drop_target = obj; Gui_Widget *wdg = data; - DnD_Info *di = NULL; + DnD_Main_Obj_Info *di = NULL; Eo *wdg_eo = NULL; Gui_Context *ctx = _active_context_get(); if (!ctx) return; @@ -2627,7 +2695,7 @@ _drop_target_pos(void *data, Eo *obj, Evas_Coord x, Evas_Coord y, Elm_Xdnd_Actio /* This callback is called only when widget is dragged, * so wdg is not NULL. */ void -_drag_start_cb(const Gui_Widget *wdg, const Eo *_wdg_eo) +_drag_start_post_cb(const Gui_Widget *wdg, const Eo *_wdg_eo) { Eo *wdg_eo = (Eo *) _wdg_eo; eo_do(wdg_eo, efl_gfx_visible_set(EINA_FALSE)); @@ -2789,7 +2857,7 @@ _widget_add(Gui_Session *session, const Gui_Widget *wdg, void *data) eo_do(iwin, eo_event_callback_add(EVAS_OBJECT_EVENT_MOUSE_DOWN, _mouse_down_main, wdg)); eo_do(iwin, eo_event_callback_add(EVAS_OBJECT_EVENT_MOUSE_UP, _mouse_up_main, wdg)); - DnD_Info *di = calloc (1, sizeof(DnD_Info)); + DnD_Main_Obj_Info *di = calloc (1, sizeof(DnD_Main_Obj_Info)); wdg_data_set(wdg, EDITOR_DND_DATA, di); drop_target_main_wdg_set((Gui_Widget *) wdg, fr, _drop_target_main_wdg_enter, (void *) wdg, @@ -2851,7 +2919,7 @@ _widget_del(Gui_Session *session, const Gui_Widget *wdg, void *data EINA_UNUSED) objtree_item_remove(wdg); session_wdg_existence_set(session, wdg, EINA_FALSE); - DnD_Info *di = wdg_data_get(wdg, EDITOR_DND_DATA); + DnD_Main_Obj_Info *di = wdg_data_get(wdg, EDITOR_DND_DATA); if (di) { free(di); @@ -3607,7 +3675,7 @@ _editor_factory_wdg_create(const char *class_name, const Gui_Widget *focused_wdg void editor_shutdown() { - DnD_Info *di = eo_do_ret(g->main_win->canvas_scroller, di, eo_key_data_get(EDITOR_DND_DATA)); + DnD_Main_Obj_Info *di = eo_do_ret(g->main_win->canvas_scroller, di, eo_key_data_get(EDITOR_DND_DATA)); eo_do(g->main_win->canvas_scroller, eo_key_data_del(EDITOR_DND_DATA)); free(di); drop_target_wdg_del(NULL, g->main_win->canvas_scroller); @@ -5080,7 +5148,7 @@ editor_init(GuiLogicCbs *_guilogic_cbs) target_db_init(); ecore_idle_enterer_add(_wdg_border_draw_on_idle, NULL); - DnD_Info *di = calloc (1, sizeof(DnD_Info)); + DnD_Main_Obj_Info *di = calloc (1, sizeof(DnD_Main_Obj_Info)); eo_do(g->main_win->canvas_scroller, eo_key_data_set(EDITOR_DND_DATA, di)); drop_target_main_wdg_set(NULL, g->main_win->canvas_scroller, _drop_target_main_wdg_enter, NULL, @@ -5090,6 +5158,7 @@ editor_init(GuiLogicCbs *_guilogic_cbs) ); drop_item_container_set(g->main_win->objtree_list, _objtree_it_get_cb, _objtree_drop_cb, NULL); + drag_item_container_set(g->main_win->objtree_list, 0.5, 0.3, _objtree_it_get_cb, _objtree_data_getcb); key_binding_new(_key_binding_undo_cb, NULL, "ctrl", "z", NULL); key_binding_new(_key_binding_redo_cb, NULL, "ctrl", "shift", "z", NULL); --
