summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYakov Goldberg <yakov.g@samsung.com>2014-11-24 12:06:55 +0200
committerYakov Goldberg <yakov.g@samsung.com>2014-12-14 18:54:24 +0200
commit0973d443c3374197828ee6e56d4065b9d1e236f2 (patch)
tree2d810c720f106a336f492066b8d496b1c863f256
parent7ca86758789309f3af4c2d8b8873e93740e1fe30 (diff)
DnD. Part 2drag_and_drop
-rw-r--r--src/bin/egui_gui/dnd.c89
-rw-r--r--src/bin/egui_gui/dnd.h15
-rw-r--r--src/bin/egui_gui/editor.c790
-rw-r--r--src/lib/ffi_abstraction.c4
-rw-r--r--src/lib/gui_widget.c11
-rw-r--r--src/lib/gui_widget.h13
6 files changed, 724 insertions, 198 deletions
diff --git a/src/bin/egui_gui/dnd.c b/src/bin/egui_gui/dnd.c
index 1543d09..a47f4bf 100644
--- a/src/bin/egui_gui/dnd.c
+++ b/src/bin/egui_gui/dnd.c
@@ -11,12 +11,16 @@ typedef struct
11 const char *data; /*DnD data*/ 11 const char *data; /*DnD data*/
12 Eo *image; /* image for DnD icon. */ 12 Eo *image; /* image for DnD icon. */
13 Eo *obj; /*object, where drag starts */ 13 Eo *obj; /*object, where drag starts */
14 const Gui_Widget *wdg; /* let's think about it as about DnD data. */
15
16 void (*_drag_start_cb)(const Gui_Widget *wdg, const Eo *obj);
14} Drag_Info; 17} Drag_Info;
15 18
16typedef struct 19typedef struct
17{ 20{
18 Ecore_Timer *tm; 21 Ecore_Timer *tm;
19 Drag_Info *drag_info; 22 Drag_Info *drag_info;
23 int dnd_in_out; /* Main objects enter/leave counter*/
20} DnD_Info; 24} DnD_Info;
21 25
22typedef struct 26typedef struct
@@ -41,6 +45,12 @@ typedef struct
41 45
42static DnD_Info _dnd_info; 46static DnD_Info _dnd_info;
43 47
48/* Determine if dragged object is inside droppable. */
49Eina_Bool
50dnd_is_in_drop_target()
51{
52 return !!_dnd_info.dnd_in_out;
53}
44 54
45const char* 55const char*
46dnd_drag_data_get() 56dnd_drag_data_get()
@@ -48,6 +58,18 @@ dnd_drag_data_get()
48 return _dnd_info.drag_info->data; 58 return _dnd_info.drag_info->data;
49} 59}
50 60
61const Eo*
62dnd_drag_obj_get()
63{
64 return _dnd_info.drag_info->obj;
65}
66
67const Gui_Widget*
68dnd_drag_wdg_get()
69{
70 return _dnd_info.drag_info->wdg;
71}
72
51static void 73static void
52_dragpos(void *data EINA_UNUSED, Eo * obj EINA_UNUSED, Evas_Coord x EINA_UNUSED, Evas_Coord y EINA_UNUSED, Elm_Xdnd_Action action EINA_UNUSED) 74_dragpos(void *data EINA_UNUSED, Eo * obj EINA_UNUSED, Evas_Coord x EINA_UNUSED, Evas_Coord y EINA_UNUSED, Elm_Xdnd_Action action EINA_UNUSED)
53{ 75{
@@ -72,6 +94,7 @@ _dragstate(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED)
72static void 94static void
73_dropenter(void *data, Evas_Object *obj) 95_dropenter(void *data, Evas_Object *obj)
74{ 96{
97 _dnd_info.dnd_in_out++;
75 Target_Info *ti = data; 98 Target_Info *ti = data;
76 ti->drop_target = ti->wdg; 99 ti->drop_target = ti->wdg;
77 100
@@ -86,6 +109,7 @@ static void
86_dropleave(void *data, Evas_Object *obj) 109_dropleave(void *data, Evas_Object *obj)
87{ 110{
88 Target_Info *main_wdg_ti = data; 111 Target_Info *main_wdg_ti = data;
112 _dnd_info.dnd_in_out--;
89 113
90 /* if ti->drop_target is not current main widget, then it means, 114 /* if ti->drop_target is not current main widget, then it means,
91 * that prev drop target, box for example wasn't leaved properly. 115 * that prev drop target, box for example wasn't leaved properly.
@@ -125,7 +149,7 @@ _dropcb(void *data EINA_UNUSED, Evas_Object *obj, Elm_Selection_Data *ev)
125} 149}
126 150
127static void 151static void
128_drop_target_iterate(Gui_Widget **drop_candidate, Gui_Session *session, Evas_Coord x, Evas_Coord y) 152_drop_target_iterate(Gui_Widget **drop_candidate, const Gui_Session *session, Evas_Coord x, Evas_Coord y)
129{ 153{
130 Eina_Bool stop = EINA_TRUE; 154 Eina_Bool stop = EINA_TRUE;
131 Dep_Id *wdg_id; 155 Dep_Id *wdg_id;
@@ -134,13 +158,18 @@ _drop_target_iterate(Gui_Widget **drop_candidate, Gui_Session *session, Evas_Coo
134 double aprx = 0.05; 158 double aprx = 0.05;
135 159
136 const Eina_List *lst, *l; 160 const Eina_List *lst, *l;
161 const Gui_Widget *dragged_wdg = dnd_drag_wdg_get();
137 lst = wdg_children_list_get(*drop_candidate); 162 lst = wdg_children_list_get(*drop_candidate);
138 EINA_LIST_FOREACH(lst, l, wdg_id) 163 EINA_LIST_FOREACH(lst, l, wdg_id)
139 { 164 {
140 Gui_Widget *w = wdg_get(wdg_id); 165 Gui_Widget *w = wdg_get(wdg_id);
141 /* if widget is not active, or is not a drop target, continue. */ 166 /* If widget is not active, or is not a drop target, continue. */
142 if (!w || !wdg_data_get(w, DROP_TARGET)) 167 if (!w || !wdg_data_get(w, DROP_TARGET))
143 continue; 168 continue;
169 /* If iterated object is dragged one, continue.
170 * This can happen when start dragging some drop target. */
171 if (w == dragged_wdg)
172 continue;
144 o = session_eo_get(session, w); 173 o = session_eo_get(session, w);
145 eo_do(o, evas_obj_position_get(&ox, &oy)); 174 eo_do(o, evas_obj_position_get(&ox, &oy));
146 eo_do(o, evas_obj_size_get(&ow, &oh)); 175 eo_do(o, evas_obj_size_get(&ow, &oh));
@@ -172,7 +201,6 @@ _droppos(void *data, Eo *obj, Evas_Coord x, Evas_Coord y, Elm_Xdnd_Action action
172 /* For canvas only*/ 201 /* For canvas only*/
173 if (!wdg) 202 if (!wdg)
174 { 203 {
175 ERR("drop target: MAIN CANVAS:: %d %d", x, y);
176 if (main_wdg_ti->drop_target_pos) 204 if (main_wdg_ti->drop_target_pos)
177 { 205 {
178 main_wdg_ti->drop_target_pos(main_wdg_ti->posdata, obj, x, y, action); 206 main_wdg_ti->drop_target_pos(main_wdg_ti->posdata, obj, x, y, action);
@@ -180,8 +208,6 @@ _droppos(void *data, Eo *obj, Evas_Coord x, Evas_Coord y, Elm_Xdnd_Action action
180 return; 208 return;
181 } 209 }
182 210
183 ERR("drop target: %s:: %d %d", wdg_name_get(wdg), x, y);
184
185 Eo *wdg_eo, *iwin; 211 Eo *wdg_eo, *iwin;
186 Evas_Coord p_x = 0, p_y = 0; 212 Evas_Coord p_x = 0, p_y = 0;
187 Evas_Coord iwin_x = 0, iwin_y = 0; 213 Evas_Coord iwin_x = 0, iwin_y = 0;
@@ -256,7 +282,8 @@ _droppos(void *data, Eo *obj, Evas_Coord x, Evas_Coord y, Elm_Xdnd_Action action
256static Evas_Object * 282static Evas_Object *
257_image_create_icon(void *data, Evas_Object *parent, Evas_Coord *xoff, Evas_Coord *yoff) 283_image_create_icon(void *data, Evas_Object *parent, Evas_Coord *xoff, Evas_Coord *yoff)
258{ 284{
259 Evas_Object *ic; 285 //if (!data) return NULL;
286 Evas_Object *ic = NULL;
260 Evas_Object *io = data; 287 Evas_Object *io = data;
261 const char *f, *g; 288 const char *f, *g;
262 Evas_Coord x, y, w, h, xm, ym; 289 Evas_Coord x, y, w, h, xm, ym;
@@ -280,14 +307,23 @@ static Eina_Bool
280_drag_start(void *data) 307_drag_start(void *data)
281{ 308{
282 Drag_Info *di = data; 309 Drag_Info *di = data;
310 Evas_Object *(*image_create_icon_f)(void *data, Evas_Object *parent, Evas_Coord *xoff, Evas_Coord *yoff) = NULL;
311 Evas_Object *drag_image = di->image;
312 if (drag_image)
313 image_create_icon_f = _image_create_icon;
314
283 _dnd_info.tm = NULL; 315 _dnd_info.tm = NULL;
284 _dnd_info.drag_info = di; 316 _dnd_info.drag_info = di;
285 elm_drag_start(di->obj, ELM_SEL_FORMAT_TEXT, 317 elm_drag_start(di->obj, ELM_SEL_FORMAT_TEXT,
286 di->data, ELM_XDND_ACTION_COPY, 318 di->data, ELM_XDND_ACTION_COPY,
287 _image_create_icon, di->image, 319 image_create_icon_f, drag_image,
288 _dragpos, "drag", 320 _dragpos, NULL,
289 _dragaccept, NULL, 321 _dragaccept, NULL,
290 _dragstate, "drag"); 322 _dragstate, NULL);
323 if (di->_drag_start_cb)
324 {
325 di->_drag_start_cb(di->wdg, di->obj);
326 }
291 return ECORE_CALLBACK_CANCEL; 327 return ECORE_CALLBACK_CANCEL;
292} 328}
293 329
@@ -319,9 +355,12 @@ _drag_data_free(void *data, Eo *obj EINA_UNUSED, const Eo_Event_Description *des
319{ 355{
320 Drag_Info *di = data; 356 Drag_Info *di = data;
321 free(di); 357 free(di);
358 _dnd_info.drag_info = NULL;
322 return EO_CALLBACK_CONTINUE; 359 return EO_CALLBACK_CONTINUE;
323} 360}
324 361
362/* Function to make Eo object draggable, when mouse down/up are handled inside.
363 * Dragging from factory. */
325void 364void
326drag_add(Eo *obj, Eo *image, const char *data) 365drag_add(Eo *obj, Eo *image, const char *data)
327{ 366{
@@ -333,6 +372,38 @@ drag_add(Eo *obj, Eo *image, const char *data)
333 eo_do(obj, eo_event_callback_add(EVAS_OBJECT_EVENT_DEL, _drag_data_free, di)); 372 eo_do(obj, eo_event_callback_add(EVAS_OBJECT_EVENT_DEL, _drag_data_free, di));
334} 373}
335 374
375/* Function to start dragging, when mouse down/up are handled outside.
376 * Dragging widgets. */
377void
378drag_start(Eo *obj, Eo *image, const char *data, const Gui_Widget *wdg, void (*cb)(const Gui_Widget *, const Eo *))
379{
380 Drag_Info *di = calloc(1, sizeof(Drag_Info));
381 di->image = image;
382 di->data = data;
383 di->obj = obj;
384 di->wdg = wdg;
385 di->_drag_start_cb = cb;
386 _dnd_info.drag_info = di;
387
388 ecore_timer_del(_dnd_info.tm);
389 _dnd_info.tm = ecore_timer_add(TIME_TO_DRAG, _drag_start, di);
390}
391
392/* Function to stop dragging, when mouse down/up are handled outside.
393 * Dragging widgets. */
394void
395drag_stop()
396{
397 if (_dnd_info.tm)
398 {
399 ecore_timer_del(_dnd_info.tm);
400 _dnd_info.tm = NULL;
401 }
402 free(_dnd_info.drag_info);
403 _dnd_info.drag_info = NULL;
404 _dnd_info.dnd_in_out = 0;
405}
406
336static Target_Info* 407static Target_Info*
337_target_info_new(Gui_Widget *wdg, Eo *obj) 408_target_info_new(Gui_Widget *wdg, Eo *obj)
338{ 409{
diff --git a/src/bin/egui_gui/dnd.h b/src/bin/egui_gui/dnd.h
index 8f214b5..bb7d6c3 100644
--- a/src/bin/egui_gui/dnd.h
+++ b/src/bin/egui_gui/dnd.h
@@ -6,6 +6,12 @@ void
6drag_add(Eo *obj, Eo *image, const char *data); 6drag_add(Eo *obj, Eo *image, const char *data);
7 7
8void 8void
9drag_start(Eo *obj, Eo *image, const char *data, const Gui_Widget *wdg, void (*cb)(const Gui_Widget *, const Eo *));
10
11void
12drag_stop();
13
14void
9drop_target_wdg_set(Gui_Widget *wdg, 15drop_target_wdg_set(Gui_Widget *wdg,
10 void (*drop_target_enter)(void *, Evas_Object *obj), void *enterdata, 16 void (*drop_target_enter)(void *, Evas_Object *obj), void *enterdata,
11 void (*drop_target_leave)(void *, Evas_Object *obj), void *leavedata, 17 void (*drop_target_leave)(void *, Evas_Object *obj), void *leavedata,
@@ -25,4 +31,13 @@ drop_target_wdg_del(Gui_Widget *wdg, Eo *obj);
25const char* 31const char*
26dnd_drag_data_get(); 32dnd_drag_data_get();
27 33
34const Eo*
35dnd_drag_obj_get();
36
37const Gui_Widget*
38dnd_drag_wdg_get();
39
40Eina_Bool
41dnd_is_in_drop_target();
42
28#endif 43#endif
diff --git a/src/bin/egui_gui/editor.c b/src/bin/egui_gui/editor.c
index d20859f..5ec816f 100644
--- a/src/bin/egui_gui/editor.c
+++ b/src/bin/egui_gui/editor.c
@@ -28,6 +28,33 @@
28#define CURSOR_DROP_X "cursor_drop_x" 28#define CURSOR_DROP_X "cursor_drop_x"
29#define CURSOR_DROP_Y "cursor_drop_y" 29#define CURSOR_DROP_Y "cursor_drop_y"
30 30
31#define EDITOR_DND_DATA "__EDITOR_DND_DATA__"
32#define EDITOR_DRAG_DATA "__EDITOR_DRAG_DATA__"
33#define DND_SESSION "__DND_SESSION__"
34
35typedef struct
36{
37 Eo *eo_cur;
38
39 Eina_Bool packed; /* Need this, because no API to check if object is packed into table
40 and unpack causes error message. */
41 int box_pack_idx;
42
43 int cell_part_x; /* Which fifth part of sell was selected*/
44 int cell_part_y; /* Used in order to check if need to repack or not. */
45
46 int table_w; /* Table width/height. Calculate it once in the beginning. */
47 int table_h;
48
49 int table_pack_x;
50 int table_pack_y;
51 Eina_List *table_borders;
52
53 int pointer_x;
54 int pointer_y;
55}
56DnD_Info;
57
31/* Function to call in the end of undo/redo in order to update view. 58/* Function to call in the end of undo/redo in order to update view.
32 * Update is made according to head memento. */ 59 * Update is made according to head memento. */
33static void 60static void
@@ -297,7 +324,6 @@ _wdg_border_draw(const Gui_Widget *wdg, Eina_Bool visibility, int border_type_co
297 } 324 }
298 } 325 }
299 326
300
301 switch (border_type_color) 327 switch (border_type_color)
302 { 328 {
303 case BORDER_SELECTION: 329 case BORDER_SELECTION:
@@ -332,46 +358,6 @@ _wdg_border_draw(const Gui_Widget *wdg, Eina_Bool visibility, int border_type_co
332#undef STR 358#undef STR
333 359
334static void 360static void
335_on_mouse_move_widget_drag(void *data, Evas *e EINA_UNUSED, Evas_Object *obj,
336void *event_info)
337{
338 Gui_Context *ctx = data;
339 static int cx, cy;
340 Evas_Coord ox, oy;
341 Evas_Event_Mouse_Move *ev = event_info;
342
343 /*FIXME: remove static stuff after tripple callback wil be fixed*/
344 if ((cx == ev->cur.canvas.x) && (cy == ev->cur.canvas.y))
345 return;
346
347 eo_do(obj, evas_obj_position_get(&ox, &oy));
348 ox = ox + (ev->cur.canvas.x - ev->prev.canvas.x);
349 oy = oy + (ev->cur.canvas.y - ev->prev.canvas.y);
350
351 eo_do(obj, evas_obj_position_set(ox, oy));
352 {
353 Gui_Widget *wdg = wdg_find_by_eo(gui_context_editor_session_get(ctx), ctx, obj);
354 Gui_Widget_Property *prop;
355 Gui_Value *val;
356
357 if (wdg)
358 {
359 prop = wdg_prop_get(wdg, DB_DEF_EVAS_OBJECT_CLASS, POSITION_SET);
360 if (prop)
361 {
362 val = prop_value_nth_get(prop, 0);
363 gui_value_int_set(val, ox);
364 val = prop_value_nth_get(prop, 1);
365 gui_value_int_set(val, oy);
366 propview_item_update(prop);
367 }
368 }
369 }
370 cx = ev->cur.canvas.x;
371 cy = ev->cur.canvas.y;
372}
373
374static void
375_frame_mouse_move(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *fr, void *event_info) 361_frame_mouse_move(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *fr, void *event_info)
376{ 362{
377 Evas_Coord ox, oy; 363 Evas_Coord ox, oy;
@@ -508,34 +494,91 @@ _key_down(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNU
508 ERR("key down"); 494 ERR("key down");
509} 495}
510 496
511/* Callback, which adds MOUSE_MOVE callback,
512 * to implement drag-and-drop in editor mode*/
513static void 497static void
514_mouse_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED) 498_drag_widget_iterate(Gui_Widget **drag_candidate, const Gui_Session *session, Evas_Coord x, Evas_Coord y)
515{ 499{
516 Gui_Context *ctx = data; 500 Eina_Bool stop = EINA_TRUE;
517 const Gui_Session *session = gui_context_editor_session_get(ctx); 501 Dep_Id *wdg_id;
518 Gui_Widget *wdg = wdg_find_by_eo(session, ctx, obj); 502 Eo *o;
519 EINA_SAFETY_ON_NULL_RETURN(wdg); 503 Evas_Coord ox, oy, ow, oh;
504 double aprx = 0.05;
505
506 const Eina_List *lst, *l;
507 lst = wdg_children_list_get(*drag_candidate);
508 EINA_LIST_FOREACH(lst, l, wdg_id)
509 {
510 Gui_Widget *w = wdg_get(wdg_id);
511 /* if widget is not active, continue. */
512 if (!w)
513 continue;
514 o = session_eo_get(session, w);
515 eo_do(o, evas_obj_position_get(&ox, &oy));
516 eo_do(o, evas_obj_size_get(&ow, &oh));
517 if (((x >= ox) && (x <= ox + ow)) &&
518 ((y >= oy) && (y <= oy + oh)))
519 {
520 *drag_candidate = w;
521 /* Suppose we have win, a resize object box, and a table packed into the box.
522 * We drag, so want to enter the box first, and table after.
523 * So while pointer in in 5% of width of the box, force to return the box as a drop target. */
524 if (((x > ox + (Evas_Coord) (ow * aprx)) && (x <= ox + (Evas_Coord) (ow * (1- aprx)))) &&
525 ((y > oy + (Evas_Coord) (oh * aprx)) && (y <= oy + (Evas_Coord) (oh * (1- aprx)))))
526 stop = EINA_FALSE;
527 }
528 }
529
530 if (!stop)
531 _drag_widget_iterate(drag_candidate, session, x, y);
532}
533
534void
535_drag_start_cb(const Gui_Widget *wdg, const Eo *_wdg_eo);
536
537/* Callback, called on mouse_down on window image,
538 * resolves widget under a cursor. */
539static void
540_mouse_down_main(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info)
541{
542 Eo *wdg_eo = NULL;
543 Evas_Event_Mouse_Down *ev = event_info;
544 Gui_Widget *wdg_main = data, *drag_candidate = NULL, *wdg;
545 const Gui_Session *session = gui_context_editor_session_get(wdg_context_get(wdg_main));
546 drag_candidate = wdg_main;
547 Evas_Coord x, y;
548 eo_do(obj, evas_obj_position_get(&x, &y));
549 _drag_widget_iterate(&drag_candidate, session, ev->canvas.x - x, ev->canvas.y - y);
550
551 wdg = drag_candidate;
552 wdg_eo = session_eo_get(session, wdg);
553
554 drag_start(wdg_eo, NULL, EDITOR_DRAG_DATA, wdg, _drag_start_cb);
520 555
521 Eo *wdg_eo = session_eo_get(session, wdg);
522 evas_object_focus_set(wdg_eo, EINA_TRUE); 556 evas_object_focus_set(wdg_eo, EINA_TRUE);
523 _editor_wdg_selected_set(wdg); 557 _editor_wdg_selected_set(wdg);
524 objtree_item_selected_set(wdg); 558 objtree_item_selected_set(wdg);
525
526 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_MOVE, _on_mouse_move_widget_drag, ctx);
527} 559}
528 560
529/* Callback, which deletes MOUSE_MOVE callback, 561/* Callback, called when depress mouse button */
530 * to implement drag-and-drop*/ 562static void
531static Eina_Bool 563_mouse_up_main(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
532_mouse_up(void *data EINA_UNUSED, Eo *obj, const Eo_Event_Description *desc EINA_UNUSED, void *event_info EINA_UNUSED)
533{ 564{
534 /* Delete all callbacks, 565 if (!dnd_is_in_drop_target())
535 * because sometimes _mouse_down is called several times. */ 566 {
536 while(evas_object_event_callback_del 567 /* Check if dragged object is visible.
537 (obj, EVAS_CALLBACK_MOUSE_MOVE, _on_mouse_move_widget_drag)); 568 * If not, means that _drag_start_cb was called, so need to reload main wdg. */
538 return EO_CALLBACK_CONTINUE; 569 const Gui_Widget *drag_widget = dnd_drag_wdg_get();
570 const Gui_Session *session = gui_context_editor_session_get(wdg_context_get(drag_widget));
571 const Eo *wdg_eo = session_eo_get(session, drag_widget);
572 Eina_Bool vis = eo_do(wdg_eo, evas_obj_visibility_get());
573
574 drag_stop();
575 _wdg_border_draw(NULL, EINA_FALSE, BORDER_DROP_TARGET);
576 if (!vis)
577 {
578 Gui_Widget *wdg_main = data;
579 _wdg_parent_win_reload(wdg_main);
580 }
581 }
539} 582}
540 583
541static Eina_Bool 584static Eina_Bool
@@ -783,7 +826,17 @@ _frame_mouse_down(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj,
783 _editor_wdg_selected_set(wdg); 826 _editor_wdg_selected_set(wdg);
784 objtree_item_selected_set(wdg); 827 objtree_item_selected_set(wdg);
785 828
786 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_MOVE, _frame_mouse_move, NULL); 829 /* Don't use dnd for dragging window around canvas. */
830 if (IS_WIN(wdg))
831 {
832 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_MOVE, _frame_mouse_move, NULL);
833 }
834 else
835 {
836 const Gui_Session *session = gui_context_editor_session_get(wdg_context_get(wdg));
837 Eo *wdg_eo = session_eo_get(session, wdg);
838 drag_start(wdg_eo, NULL, EDITOR_DRAG_DATA, wdg, _drag_start_cb);
839 }
787} 840}
788 841
789static Eina_Bool 842static Eina_Bool
@@ -1100,31 +1153,6 @@ _content_set(Gui_Session *session, const Gui_Widget *container, const Gui_Widget
1100/************ DnD Functions ******************************/ 1153/************ DnD Functions ******************************/
1101/*********************************************************/ 1154/*********************************************************/
1102 1155
1103#define EDITOR_DND_DATA "__EDITOR_DND_DATA__"
1104
1105typedef struct
1106{
1107 Eo *eo_cur;
1108
1109 Eina_Bool packed; /* Need this, because no API to check if object is packed into table
1110 and unpack causes error message. */
1111 int box_pack_idx;
1112
1113 int cell_part_x; /* Which fifth part of sell was selected*/
1114 int cell_part_y; /* Used in order to check if need to repack or not. */
1115
1116 int table_w; /* Table width/height. Calculate it once in the beginning. */
1117 int table_h;
1118
1119 int table_pack_x;
1120 int table_pack_y;
1121 Eina_List *table_borders;
1122
1123 int pointer_x;
1124 int pointer_y;
1125}
1126DnD_Info;
1127
1128/* Draw border rectangles in table cells. */ 1156/* Draw border rectangles in table cells. */
1129static inline void 1157static inline void
1130_table_borders_draw(Eo *table, int w, int h, Eina_List **_border_objects) 1158_table_borders_draw(Eo *table, int w, int h, Eina_List **_border_objects)
@@ -1157,6 +1185,50 @@ _table_borders_draw(Eo *table, int w, int h, Eina_List **_border_objects)
1157 *_border_objects = border_objects; 1185 *_border_objects = border_objects;
1158} 1186}
1159 1187
1188/* Iteration to create dragged representation of object. */
1189static Eo*
1190_iter_dragged_widget_create(Gui_Session *session, const Gui_Widget *wdg, Eo *parent_win)
1191{
1192 const Eina_List *children = NULL, *l;
1193 Dep_Id *wid;
1194
1195 /* Windows are iterated separately. If parent is NULL, means that current object is not win.
1196 * If iterated object is win, I create it as inlined_image and add frame to simulate win.*/
1197 Eo *o = _ffi_eo_add(session, wdg, parent_win);
1198
1199 if (o)
1200 {
1201 session_eo_set(session, wdg, o);
1202 manager_widget_configure(session, wdg, MODE_EDITOR, NULL);
1203 children = wdg_children_list_get(wdg);
1204 EINA_LIST_FOREACH(children, l, wid)
1205 {
1206 Gui_Widget *w = wdg_get(wid);
1207 /* Window can not have child windows, so pass NULL. */
1208 if (w) _iter_dragged_widget_create(session, w, NULL);
1209 }
1210 }
1211 return o;
1212}
1213
1214static Eo*
1215_drag_obj_create(const Gui_Widget *dragged_wdg, Eo *canvas)
1216{
1217 Eo *ret;
1218 Gui_Session *dnd_session = session_new();
1219 eo_do(canvas, eo_key_data_set(DND_SESSION, dnd_session, NULL));
1220 ret = _iter_dragged_widget_create(dnd_session, dragged_wdg, canvas);
1221 return ret;
1222}
1223
1224static void
1225_drag_obj_del(const Gui_Widget *dragged_wdg, Eo *canvas)
1226{
1227 Gui_Session *dnd_session = eo_do(canvas, eo_key_data_get(DND_SESSION));
1228 manager_widget_delete(dnd_session, dragged_wdg, MODE_EDITOR, NULL);
1229 session_del(dnd_session);
1230}
1231
1160static void 1232static void
1161_drop_target_main_wdg_enter(void *data, Evas_Object *obj) 1233_drop_target_main_wdg_enter(void *data, Evas_Object *obj)
1162{ 1234{
@@ -1167,8 +1239,8 @@ _drop_target_main_wdg_enter(void *data, Evas_Object *obj)
1167 /* If wdg == NULL, then canvas is a drop target or we have a error.*/ 1239 /* If wdg == NULL, then canvas is a drop target or we have a error.*/
1168 if (wdg) 1240 if (wdg)
1169 { 1241 {
1170 Gui_Session *session = (Gui_Session *) gui_context_editor_session_get(wdg_context_get(wdg)); 1242 const Gui_Session *session = gui_context_editor_session_get(wdg_context_get(wdg));
1171 di = wdg_data_get(wdg_main_wdg_get(wdg), EDITOR_DND_DATA); 1243 di = wdg_data_get(wdg, EDITOR_DND_DATA);
1172 canvas = session_eo_get(session, wdg); 1244 canvas = session_eo_get(session, wdg);
1173 _wdg_border_draw(wdg, EINA_TRUE, BORDER_DROP_TARGET); 1245 _wdg_border_draw(wdg, EINA_TRUE, BORDER_DROP_TARGET);
1174 } 1246 }
@@ -1184,13 +1256,25 @@ _drop_target_main_wdg_enter(void *data, Evas_Object *obj)
1184 } 1256 }
1185 1257
1186 const Eo_Class* (*kl_func)(); 1258 const Eo_Class* (*kl_func)();
1187 kl_func = db_class_func_get(dnd_drag_data_get()); 1259 const char * _drag_data = dnd_drag_data_get(), *drag_obj_class_name;
1188 if (di->eo_cur) eo_del(di->eo_cur); 1260 const Gui_Widget *dragged_wdg = dnd_drag_wdg_get();
1189 di->eo_cur = eo_add(kl_func(), canvas); 1261
1190 eo_do(di->eo_cur, evas_obj_size_set(80, 30)); 1262 ERR("di: %p; obj: %p", di, obj);
1191 eo_do(di->eo_cur, evas_obj_size_hint_weight_set(EVAS_HINT_EXPAND, EVAS_HINT_EXPAND)); 1263 if (!di->eo_cur)
1192 eo_do(di->eo_cur, evas_obj_visibility_set(EINA_TRUE)); 1264 {
1193 eo_do(di->eo_cur, elm_obj_widget_part_text_set(NULL, dnd_drag_data_get())); 1265 if (dragged_wdg)
1266 {
1267 di->eo_cur = _drag_obj_create(dragged_wdg, canvas);
1268 }
1269 else
1270 {
1271 drag_obj_class_name = _drag_data;
1272 kl_func = db_class_func_get(drag_obj_class_name);
1273 di->eo_cur = eo_add(kl_func(), canvas);
1274 eo_do(di->eo_cur, evas_obj_visibility_set(EINA_TRUE),
1275 elm_obj_widget_part_text_set(NULL, drag_obj_class_name));
1276 }
1277 }
1194} 1278}
1195 1279
1196static void 1280static void
@@ -1198,22 +1282,37 @@ _drop_target_main_wdg_leave(void *data, Evas_Object *obj)
1198{ 1282{
1199 Gui_Widget *wdg = data; 1283 Gui_Widget *wdg = data;
1200 Eo *canvas_drop_target = obj; 1284 Eo *canvas_drop_target = obj;
1285 Eo *canvas = NULL;
1201 DnD_Info *di; 1286 DnD_Info *di;
1202 if (wdg) 1287 if (wdg)
1203 { 1288 {
1204 di = wdg_data_get(wdg_main_wdg_get(wdg), EDITOR_DND_DATA); 1289 di = wdg_data_get(wdg, EDITOR_DND_DATA);
1290 const Gui_Session *session = gui_context_editor_session_get(wdg_context_get(wdg));
1291 canvas = session_eo_get(session, wdg);
1205 } 1292 }
1206 else if (canvas_drop_target != NULL) 1293 else if (canvas_drop_target != NULL)
1207 { 1294 {
1208 di = eo_do(canvas_drop_target, eo_key_data_get(EDITOR_DND_DATA)); 1295 di = eo_do(canvas_drop_target, eo_key_data_get(EDITOR_DND_DATA));
1296 canvas = canvas_drop_target;
1209 } 1297 }
1210 else 1298 else
1211 { 1299 {
1212 ERR("Drop target is wrong. If you see this message something is terribly wrong!"); 1300 ERR("Drop target is wrong. If you see this message something is terribly wrong!");
1213 } 1301 }
1214 1302
1215 eo_del(di->eo_cur); 1303 if (di->eo_cur)
1216 di->eo_cur = NULL; 1304 {
1305 const Gui_Widget *dragged_wdg = dnd_drag_wdg_get();
1306 if (dragged_wdg)
1307 {
1308 _drag_obj_del(dragged_wdg, canvas);
1309 }
1310 else
1311 {
1312 eo_del(di->eo_cur);
1313 }
1314 di->eo_cur = NULL;
1315 }
1217} 1316}
1218 1317
1219static void 1318static void
@@ -1222,11 +1321,10 @@ _drop_target_enter(void *data, Evas_Object *obj EINA_UNUSED)
1222 Gui_Widget *wdg = data; 1321 Gui_Widget *wdg = data;
1223 _wdg_border_draw(wdg, EINA_TRUE, BORDER_DROP_TARGET); 1322 _wdg_border_draw(wdg, EINA_TRUE, BORDER_DROP_TARGET);
1224 Eo *wdg_eo = NULL; 1323 Eo *wdg_eo = NULL;
1225 ERR("Enter: %s", wdg_name_get(wdg));
1226 DnD_Info *di = wdg_data_get(wdg_main_wdg_get(wdg), EDITOR_DND_DATA); 1324 DnD_Info *di = wdg_data_get(wdg_main_wdg_get(wdg), EDITOR_DND_DATA);
1227 if (!IS_MAIN(wdg)) 1325 if (!IS_MAIN(wdg))
1228 { 1326 {
1229 Gui_Session *session = (Gui_Session *) gui_context_editor_session_get(wdg_context_get(wdg)); 1327 const Gui_Session *session = gui_context_editor_session_get(wdg_context_get(wdg));
1230 wdg_eo = session_eo_get(session, wdg); 1328 wdg_eo = session_eo_get(session, wdg);
1231 } 1329 }
1232 if (wdg_eo && !strcmp(wdg_class_name_get(wdg), DB_DEF_BOX_CLASS)) 1330 if (wdg_eo && !strcmp(wdg_class_name_get(wdg), DB_DEF_BOX_CLASS))
@@ -1263,10 +1361,11 @@ _drop_target_leave(void *data, Evas_Object *obj EINA_UNUSED)
1263 ERR("LEave: %s", wdg_name_get(wdg)); 1361 ERR("LEave: %s", wdg_name_get(wdg));
1264 DnD_Info *di = wdg_data_get(wdg_main_wdg_get(wdg), EDITOR_DND_DATA); 1362 DnD_Info *di = wdg_data_get(wdg_main_wdg_get(wdg), EDITOR_DND_DATA);
1265 Eo *wdg_eo = NULL; 1363 Eo *wdg_eo = NULL;
1364 const Gui_Context *ctx = wdg_context_get(wdg);
1365 const Gui_Session *session = gui_context_editor_session_get(ctx);
1266 /* Coordinates of object relative to canvas. */ 1366 /* Coordinates of object relative to canvas. */
1267 if (!IS_MAIN(wdg)) 1367 if (!IS_MAIN(wdg))
1268 { 1368 {
1269 Gui_Session *session = (Gui_Session *) gui_context_editor_session_get(wdg_context_get(wdg));
1270 wdg_eo = session_eo_get(session, wdg); 1369 wdg_eo = session_eo_get(session, wdg);
1271 } 1370 }
1272 if (wdg_eo && !strcmp(wdg_class_name_get(wdg), DB_DEF_BOX_CLASS)) 1371 if (wdg_eo && !strcmp(wdg_class_name_get(wdg), DB_DEF_BOX_CLASS))
@@ -1290,7 +1389,6 @@ _drop_target_leave(void *data, Evas_Object *obj EINA_UNUSED)
1290 di->table_borders = NULL; 1389 di->table_borders = NULL;
1291 eo_do(wdg_eo, elm_obj_table_unpack(di->eo_cur)); 1390 eo_do(wdg_eo, elm_obj_table_unpack(di->eo_cur));
1292 1391
1293 Gui_Session *session = (Gui_Session *) gui_context_editor_session_get(wdg_context_get(wdg));
1294 Eina_List *lst = wdg_obj_container_contents_list_get(wdg), *l; 1392 Eina_List *lst = wdg_obj_container_contents_list_get(wdg), *l;
1295 Object_Container_Item *it; 1393 Object_Container_Item *it;
1296 EINA_LIST_FOREACH(lst, l, it) 1394 EINA_LIST_FOREACH(lst, l, it)
@@ -1319,114 +1417,328 @@ _drop_target_drop(void *data, Evas_Object *obj, Elm_Selection_Data *ev)
1319{ 1417{
1320 Gui_Widget *wdg = data; 1418 Gui_Widget *wdg = data;
1321 Eo *canvas_drop_target = obj; 1419 Eo *canvas_drop_target = obj;
1420 Eo *canvas = NULL;
1322 DnD_Info *di; 1421 DnD_Info *di;
1323 _wdg_border_draw(NULL, EINA_FALSE, BORDER_DROP_TARGET); 1422 _wdg_border_draw(NULL, EINA_FALSE, BORDER_DROP_TARGET);
1324 if (wdg) 1423 if (wdg)
1325 { 1424 {
1326 di = wdg_data_get(wdg_main_wdg_get(wdg), EDITOR_DND_DATA); 1425 di = wdg_data_get(wdg_main_wdg_get(wdg), EDITOR_DND_DATA);
1426 const Gui_Session *session = gui_context_editor_session_get(wdg_context_get(wdg));
1427 canvas = session_eo_get(session, wdg_main_wdg_get(wdg));
1327 } 1428 }
1328 else if (canvas_drop_target != NULL) 1429 else if (canvas_drop_target != NULL)
1329 { 1430 {
1330 di = eo_do(canvas_drop_target, eo_key_data_get(EDITOR_DND_DATA)); 1431 di = eo_do(canvas_drop_target, eo_key_data_get(EDITOR_DND_DATA));
1432 canvas = canvas_drop_target;
1331 } 1433 }
1332 else 1434 else
1333 { 1435 {
1334 ERR("Drop target is wrong. If you see this message something is terribly wrong!"); 1436 ERR("Drop target is wrong. If you see this message something is terribly wrong!");
1335 } 1437 }
1336 1438
1337 if (di->eo_cur) eo_del(di->eo_cur);
1338
1339 const char *drag_data = ev->data; 1439 const char *drag_data = ev->data;
1340 Gui_Widget *new_wdg = _editor_factory_wdg_create(drag_data, wdg, di->pointer_x, di->pointer_y); 1440 const Gui_Widget *new_wdg = NULL;
1441 const Gui_Context *ctx = _active_context_get();
1442 const Gui_Session *session = gui_context_editor_session_get(ctx);
1443 if (strcmp(drag_data, EDITOR_DRAG_DATA))
1444 {
1445 /* Don't allow to drop Window from factory into Main Obj*/
1446 if (!strcmp(DB_DEF_WIN_CLASS , drag_data) && wdg)
1447 {
1448 goto end;
1449 }
1450 new_wdg = _editor_factory_wdg_create(drag_data, wdg, di->pointer_x, di->pointer_y);
1451 }
1452 else
1453 {
1454 new_wdg = dnd_drag_wdg_get();
1455 }
1341 1456
1342 if (wdg && !strcmp(wdg_class_name_get(wdg), DB_DEF_BOX_CLASS)) 1457 /* Check if new_widget was packed previously: take it's parent and check
1458 * if widget is packed into it's parent.
1459 * If so, we need to unpack widget and delete from contents*/
1460 Gui_Widget *wdg_parent = (Gui_Widget *) wdg_parent_get(new_wdg), *prev_wdg_container = NULL;
1461 if (wdg_parent && wdg_obj_container_item_get(wdg_parent, -1, wdg_name_get(new_wdg)))
1462 prev_wdg_container = wdg_parent;
1463
1464 /* Dragging inside the same container. */
1465 if (prev_wdg_container && (prev_wdg_container == wdg))
1343 { 1466 {
1344 /* Append content memento to the creation memento (which was created in _editor_factory_wdg_create() 1467 /* Dragging inside the same box, just reorder items. */
1345 * in order to correctly manage internals. */ 1468 if (!strcmp(wdg_class_name_get(wdg), DB_DEF_BOX_CLASS))
1346 Object_Container *_old_container, *_new_container; 1469 {
1347 _old_container = (Object_Container *) wdg_obj_container_get(wdg); 1470 /* Get current(previous) index of draggable wdg. */
1348 _new_container = obj_container_copy(_old_container); 1471 int cur_visual_idx = wdg_obj_container_item_idx_get(wdg, wdg_dep_id_get(new_wdg), EINA_TRUE);
1472 int reorder_delta = di->box_pack_idx - cur_visual_idx;
1349 1473
1350 Gui_Memento *memento_next = gui_memento_new(wdg_dep_id_get(wdg), 1474 Object_Container *_old_container, *_new_container;
1351 MEMENTO_OBJ_CONTAINER_ITEM, 1475 _old_container = (Object_Container *) wdg_obj_container_get((Gui_Widget *) wdg);
1352 _old_container, _new_container); 1476 _new_container = obj_container_copy(_old_container);
1353 gui_memento_append((Gui_Memento *) gui_context_current_memento_get(wdg_context_get(wdg)), memento_next);
1354 wdg_obj_container_unset(wdg);
1355 wdg_obj_container_set(wdg, _new_container);
1356 1477
1357 const Op_Desc *op_desc = db_container_desc_op_desc_get(db_container_desc_get(wdg_class_name_get(wdg)), CONTAINER_PACK); 1478 obj_container_ref(_old_container);
1358 Gui_Widget_Property *prop = prop_create_for_op(op_desc); 1479 wdg_obj_container_unset((Gui_Widget *) wdg);
1359 Gui_Value *val = prop_value_nth_get(prop, 0); 1480 wdg_obj_container_set((Gui_Widget *) wdg, _new_container);
1360 gui_value_name_id_set(val, GUI_TYPE_OBJECT, wdg_dep_id_get(new_wdg));
1361 1481
1362 Object_Container_Item *ci = obj_container_item_new(prop, wdg_dep_id_get(new_wdg)); 1482 /* If anything was reordered, need to reload content. */
1363 wdg_obj_container_item_add(wdg, ci, di->box_pack_idx); 1483 if (wdg_obj_container_content_reorder(wdg, cur_visual_idx, reorder_delta))
1484 {
1485 Gui_Memento *memento = gui_memento_new(wdg_dep_id_get(wdg), MEMENTO_OBJ_CONTAINER_ITEM, _old_container, _new_container);
1486 gui_context_memento_add(_active_context_get(), memento);
1487 }
1488 obj_container_unref(_old_container);
1489 }
1490 else if (!strcmp(wdg_class_name_get(wdg), DB_DEF_TABLE_CLASS))
1491 {
1492 Object_Container_Item *ci = wdg_obj_container_item_get(wdg, -1, wdg_name_get(new_wdg));
1493 Dep_Id *ci_dep_id = obj_container_item_dep_id_get(ci);
1494 const Gui_Widget_Property *ci_prop = obj_container_item_prop_get(ci);
1495 if ((INT_GET(prop_value_nth_get(ci_prop, 1)) != di->table_pack_x) ||
1496 (INT_GET(prop_value_nth_get(ci_prop, 2)) != di->table_pack_y))
1497 {
1498 Object_Container *_old_container, *_new_container;
1499 _old_container = (Object_Container *) wdg_obj_container_get((Gui_Widget *) wdg);
1500 _new_container = obj_container_copy(_old_container);
1501
1502 Gui_Memento *memento = gui_memento_new(wdg_dep_id_get(wdg), MEMENTO_OBJ_CONTAINER_ITEM, _old_container, _new_container);
1503 gui_context_memento_add((Gui_Context *) ctx, memento);
1504
1505 Eina_List *old_lst = wdg_obj_container_contents_list_get(wdg);
1506 wdg_obj_container_unset((Gui_Widget *) wdg);
1507 wdg_obj_container_set((Gui_Widget *) wdg, _new_container);
1508
1509 /* Delete everything in new_container */
1510 wdg_obj_container_item_remove_all(wdg);
1511
1512 /* Iterate over old list and create new container items and properties.
1513 * Also get packing coordinates from Eo object and put it into property. */
1514 Eo *wdg_eo = session_eo_get(session, wdg);
1515 Object_Container_Item *it;
1516 Eina_List *l;
1517 EINA_LIST_FOREACH(old_lst, l, it)
1518 {
1519 int ix, iy, iw, ih;
1520 Gui_Widget_Property *prop = obj_container_item_prop_get(it);
1521 Dep_Id *dep_id = obj_container_item_dep_id_get(it);
1522 Gui_Widget_Property *new_prop = prop_copy(prop);
1523 Eo *c = session_eo_get(session, wdg_get(dep_id));
1524 eo_do(wdg_eo, elm_obj_table_pack_get(c, &ix, &iy, &iw, &ih));
1364 1525
1365 _wdg_parent_win_reload(new_wdg); 1526 if (dep_id == ci_dep_id)
1366 _editor_wdg_selected_set(new_wdg); 1527 {
1367 objtree_item_selected_set(new_wdg); 1528 ix = di->table_pack_x;
1529 iy = di->table_pack_y;
1530 }
1531 gui_value_int_set(prop_value_nth_get(new_prop, 1), ix);
1532 gui_value_int_set(prop_value_nth_get(new_prop, 2), iy);
1533
1534 ci = obj_container_item_new(new_prop, dep_id);
1535 wdg_obj_container_item_add((Gui_Widget *) wdg, ci, -1);
1536 }
1537 }
1538 }
1539 goto end;
1368 } 1540 }
1369 else if (wdg && !strcmp(wdg_class_name_get(wdg), DB_DEF_TABLE_CLASS)) 1541 /* Dragging inside window - only change position. */
1542 else if ((wdg_parent == wdg) && IS_WIN(wdg))
1370 { 1543 {
1371 Gui_Session *session = (Gui_Session *) gui_context_editor_session_get(wdg_context_get(wdg)); 1544 if (new_wdg)
1372 Eo *wdg_eo = session_eo_get(session, wdg); 1545 {
1373 Object_Container_Item *it; 1546 Gui_Widget_Property *old_prop, *prop;
1547 Gui_Value *val;
1548 old_prop = wdg_prop_get(new_wdg, DB_DEF_EVAS_OBJECT_CLASS, POSITION_SET);
1549 if (!old_prop)
1550 {
1551 Op_Desc *op = db_mro_op_desc_get(wdg_class_name_get(new_wdg), DB_DEF_EVAS_OBJECT_CLASS, POSITION_SET);
1552 prop = prop_create_for_op(op);
1553 }
1554 else
1555 {
1556 prop = prop_copy(old_prop);
1557 }
1374 1558
1375 Object_Container *_old_container, *_new_container; 1559 val = prop_value_nth_get(prop, 0);
1376 _old_container = (Object_Container *) wdg_obj_container_get(wdg); 1560 gui_value_int_set(val, di->pointer_x);
1377 _new_container = obj_container_copy(_old_container); 1561 val = prop_value_nth_get(prop, 1);
1562 gui_value_int_set(val, di->pointer_y);
1563 propview_item_update(prop);
1378 1564
1379 Gui_Memento *memento_next = gui_memento_new(wdg_dep_id_get(wdg), 1565 Gui_Memento *memento = NULL;
1566 memento = gui_memento_new(wdg_dep_id_get(new_wdg), MEMENTO_PROPERTY, old_prop, prop);
1567 gui_context_memento_add((Gui_Context *) ctx, memento);
1568
1569 if (old_prop)
1570 {
1571 wdg_prop_remove((Gui_Widget *) new_wdg, old_prop);
1572 }
1573 wdg_prop_add((Gui_Widget *) new_wdg, prop);
1574 }
1575 goto end;
1576 }
1577
1578 /* Dragging main wdg around canvas. */
1579 else if (!wdg_parent && !wdg)
1580 {
1581 wdg_data_set(new_wdg, CURSOR_DROP_X, (void *) (intptr_t) di->pointer_x);
1582 wdg_data_set(new_wdg, CURSOR_DROP_Y, (void *) (intptr_t) di->pointer_y);
1583 goto end;
1584 }
1585 /* If dragging from one container to another, unpack from the first one*/
1586 if (prev_wdg_container && (prev_wdg_container != wdg))
1587 {
1588 Object_Container *_old_prev_container, *_new_prev_container;
1589 _old_prev_container = (Object_Container *) wdg_obj_container_get((Gui_Widget *) prev_wdg_container);
1590 _new_prev_container = obj_container_copy(_old_prev_container);
1591 Gui_Memento *memento = gui_memento_new(wdg_dep_id_get(prev_wdg_container),
1380 MEMENTO_OBJ_CONTAINER_ITEM, 1592 MEMENTO_OBJ_CONTAINER_ITEM,
1381 _old_container, _new_container); 1593 _old_prev_container, _new_prev_container);
1382 gui_memento_append((Gui_Memento *) gui_context_current_memento_get(wdg_context_get(wdg)), memento_next); 1594 gui_context_memento_add((Gui_Context *) ctx, memento);
1595 wdg_obj_container_unset((Gui_Widget *) prev_wdg_container);
1596 wdg_obj_container_set((Gui_Widget *) prev_wdg_container, _new_prev_container);
1383 1597
1384 Eina_List *old_lst = wdg_obj_container_contents_list_get(wdg); 1598 /* Take old container's class name from content-property. */
1385 wdg_obj_container_unset(wdg); 1599 Object_Container_Item *_ci = wdg_obj_container_item_get(prev_wdg_container, -1, wdg_name_get(new_wdg));
1386 wdg_obj_container_set(wdg, _new_container); 1600 wdg_obj_container_item_remove(prev_wdg_container, _ci);
1601 }
1602 /* If dragging from a widget(window), unset parent*/
1603 else if (wdg_parent && (wdg_parent != wdg))
1604 {
1605 Gui_Memento *memento = gui_memento_new(wdg_dep_id_get(new_wdg),
1606 MEMENTO_WIDGET_PARENT,
1607 wdg_parent_id_get(new_wdg), NULL);
1608 gui_context_memento_add((Gui_Context *) ctx, memento);
1609 wdg_parent_set((Gui_Widget *) new_wdg, NULL);
1610 }
1611 else if (!wdg_parent)
1612 {
1613 Gui_Memento *memento = gui_memento_new(wdg_dep_id_get(new_wdg),
1614 MEMENTO_WIDGET_PARENT,
1615 NULL, NULL);
1616 gui_context_memento_add((Gui_Context *) ctx, memento);
1617 }
1387 1618
1388 /* Delete everythin in new_container */ 1619 if (!wdg)
1389 Eina_List *lst = wdg_obj_container_contents_list_get(wdg), *l, *l2; 1620 {
1390 EINA_LIST_FOREACH_SAFE(lst, l, l2, it) 1621 Gui_Memento *memento_next = gui_memento_new(wdg_dep_id_get(new_wdg),
1622 MEMENTO_WIDGET_PARENT,
1623 wdg_parent_id_get(new_wdg), NULL);
1624 gui_memento_append((Gui_Memento *) gui_context_current_memento_get(ctx), memento_next);
1625 wdg_parent_set((Gui_Widget *) new_wdg, NULL);
1626 if (IS_MAIN(new_wdg))
1391 { 1627 {
1392 wdg_obj_container_item_remove(wdg, it); 1628 wdg_data_set(new_wdg, CURSOR_DROP_X, (void *) (intptr_t) di->pointer_x);
1629 wdg_data_set(new_wdg, CURSOR_DROP_Y, (void *) (intptr_t) di->pointer_y);
1393 } 1630 }
1394 1631 }
1395 /* Iterate over old list and clreate new container items and properties. 1632 else if (wdg && IS_WIN(wdg))
1396 * Also get packing coordinates from Eo object and put it into property. */ 1633 {
1397 EINA_LIST_FOREACH(old_lst, l, it) 1634 Gui_Memento *memento_next = gui_memento_new(wdg_dep_id_get(new_wdg),
1635 MEMENTO_WIDGET_PARENT,
1636 wdg_parent_id_get(new_wdg), wdg_dep_id_get(wdg));
1637 gui_memento_append((Gui_Memento *) gui_context_current_memento_get(ctx), memento_next);
1638 wdg_parent_set((Gui_Widget *) new_wdg, wdg_name_get(wdg));
1639 }
1640 else
1641 {
1642 if (wdg && !strcmp(wdg_class_name_get(wdg), DB_DEF_BOX_CLASS))
1398 { 1643 {
1399 Gui_Widget_Property *prop = obj_container_item_prop_get(it); 1644 /* Append content memento to the creation memento (which was created in _editor_factory_wdg_create())
1400 Gui_Widget_Property *new_prop = prop_copy(prop); 1645 * or to memento unpacking from previous container
1401 int ix, iy, iw, ih; 1646 * in order to correctly manage internals. */
1402 Dep_Id *dep_id = obj_container_item_dep_id_get(it); 1647 Object_Container *_old_container, *_new_container;
1403 Eo *c = session_eo_get(session, wdg_get(dep_id)); 1648 _old_container = (Object_Container *) wdg_obj_container_get(wdg);
1404 eo_do(wdg_eo, elm_obj_table_pack_get(c, &ix, &iy, &iw, &ih)); 1649 _new_container = obj_container_copy(_old_container);
1650
1651 Gui_Memento *memento_next = gui_memento_new(wdg_dep_id_get(wdg),
1652 MEMENTO_OBJ_CONTAINER_ITEM,
1653 _old_container, _new_container);
1654 /* Current memento is a memento created, during _factory _widget_create earlier in this func. */
1655 gui_memento_append((Gui_Memento *) gui_context_current_memento_get(ctx), memento_next);
1656 wdg_obj_container_unset(wdg);
1657 wdg_obj_container_set(wdg, _new_container);
1405 1658
1406 gui_value_int_set(prop_value_nth_get(new_prop, 1), ix); 1659 const Op_Desc *op_desc = db_container_desc_op_desc_get(db_container_desc_get(wdg_class_name_get(wdg)), CONTAINER_PACK);
1407 gui_value_int_set(prop_value_nth_get(new_prop, 2), iy); 1660 Gui_Widget_Property *prop = prop_create_for_op(op_desc);
1661 Gui_Value *val = prop_value_nth_get(prop, 0);
1662 gui_value_name_id_set(val, GUI_TYPE_OBJECT, wdg_dep_id_get(new_wdg));
1408 1663
1409 Object_Container_Item *ci = obj_container_item_new(new_prop, dep_id); 1664 Object_Container_Item *ci = obj_container_item_new(prop, wdg_dep_id_get(new_wdg));
1410 wdg_obj_container_item_add((Gui_Widget *) wdg, ci, -1); 1665 wdg_obj_container_item_add(wdg, ci, di->box_pack_idx);
1411 } 1666 }
1667 else if (wdg && !strcmp(wdg_class_name_get(wdg), DB_DEF_TABLE_CLASS))
1668 {
1669 Eo *wdg_eo = session_eo_get(session, wdg);
1670 Object_Container_Item *it;
1671
1672 Object_Container *_old_container, *_new_container;
1673 _old_container = (Object_Container *) wdg_obj_container_get(wdg);
1674 _new_container = obj_container_copy(_old_container);
1675
1676 Gui_Memento *memento_next = gui_memento_new(wdg_dep_id_get(wdg),
1677 MEMENTO_OBJ_CONTAINER_ITEM,
1678 _old_container, _new_container);
1679 /* Current memento is a memento created, during _factory _widget_create earlier in this func. */
1680 gui_memento_append((Gui_Memento *) gui_context_current_memento_get(ctx), memento_next);
1681
1682 Eina_List *old_lst = wdg_obj_container_contents_list_get(wdg);
1683 wdg_obj_container_unset(wdg);
1684 wdg_obj_container_set(wdg, _new_container);
1685
1686 /* Delete everything in new_container */
1687 wdg_obj_container_item_remove_all(wdg);
1688
1689 /* Iterate over old list and create new container items and properties.
1690 * Also get packing coordinates from Eo object and put it into property. */
1691 Eina_List *l;
1692 EINA_LIST_FOREACH(old_lst, l, it)
1693 {
1694 Gui_Widget_Property *prop = obj_container_item_prop_get(it);
1695 Gui_Widget_Property *new_prop = prop_copy(prop);
1696 int ix, iy, iw, ih;
1697 Dep_Id *dep_id = obj_container_item_dep_id_get(it);
1698 Eo *c = session_eo_get(session, wdg_get(dep_id));
1699 eo_do(wdg_eo, elm_obj_table_pack_get(c, &ix, &iy, &iw, &ih));
1412 1700
1413 /* Add new element into the container */ 1701 gui_value_int_set(prop_value_nth_get(new_prop, 1), ix);
1414 const Op_Desc *op_desc = db_container_desc_op_desc_get(db_container_desc_get(wdg_class_name_get(wdg)), CONTAINER_PACK); 1702 gui_value_int_set(prop_value_nth_get(new_prop, 2), iy);
1415 Gui_Widget_Property *prop = prop_create_for_op(op_desc);
1416 1703
1417 gui_value_name_id_set(prop_value_nth_get(prop, 0), GUI_TYPE_OBJECT, wdg_dep_id_get(new_wdg)); 1704 Object_Container_Item *ci = obj_container_item_new(new_prop, dep_id);
1418 gui_value_int_set(prop_value_nth_get(prop, 1), di->table_pack_x); 1705 wdg_obj_container_item_add((Gui_Widget *) wdg, ci, -1);
1419 gui_value_int_set(prop_value_nth_get(prop, 2), di->table_pack_y); 1706 }
1420 gui_value_int_set(prop_value_nth_get(prop, 3), 1); 1707
1421 gui_value_int_set(prop_value_nth_get(prop, 4), 1); 1708 /* Add new element into the container */
1709 const Op_Desc *op_desc = db_container_desc_op_desc_get(db_container_desc_get(wdg_class_name_get(wdg)), CONTAINER_PACK);
1710 Gui_Widget_Property *prop = prop_create_for_op(op_desc);
1422 1711
1423 Object_Container_Item *ci = obj_container_item_new(prop, wdg_dep_id_get(new_wdg)); 1712 gui_value_name_id_set(prop_value_nth_get(prop, 0), GUI_TYPE_OBJECT, wdg_dep_id_get(new_wdg));
1424 wdg_obj_container_item_add(wdg, ci, -1); 1713 gui_value_int_set(prop_value_nth_get(prop, 1), di->table_pack_x);
1714 gui_value_int_set(prop_value_nth_get(prop, 2), di->table_pack_y);
1715 gui_value_int_set(prop_value_nth_get(prop, 3), 1);
1716 gui_value_int_set(prop_value_nth_get(prop, 4), 1);
1425 1717
1426 _wdg_parent_win_reload(new_wdg); 1718 Object_Container_Item *ci = obj_container_item_new(prop, wdg_dep_id_get(new_wdg));
1427 _editor_wdg_selected_set(new_wdg); 1719 wdg_obj_container_item_add(wdg, ci, -1);
1428 objtree_item_selected_set(new_wdg); 1720 }
1429 } 1721 }
1722end:
1723
1724 if (di->eo_cur)
1725 {
1726 const Gui_Widget *dragged_wdg = dnd_drag_wdg_get();
1727 if (dragged_wdg)
1728 {
1729 _drag_obj_del(dragged_wdg, canvas);
1730 drag_stop();
1731 }
1732 else
1733 {
1734 eo_del(di->eo_cur);
1735 }
1736 di->eo_cur = NULL;
1737 }
1738
1739 _wdg_parent_win_reload(new_wdg);
1740 _editor_wdg_selected_set(new_wdg);
1741 objtree_item_selected_set(new_wdg);
1430 1742
1431 return EINA_TRUE; 1743 return EINA_TRUE;
1432} 1744}
@@ -1447,7 +1759,6 @@ _table_cell_segment_get(int x, int y, int cell_w, int cell_h, int *_part_x, int
1447 if (_part_y) *_part_y = part_y; 1759 if (_part_y) *_part_y = part_y;
1448} 1760}
1449 1761
1450
1451/* x, y - coordinates of pointers relative to droppable object. */ 1762/* x, y - coordinates of pointers relative to droppable object. */
1452static void 1763static void
1453_drop_target_pos(void *data, Eo *obj, Evas_Coord x, Evas_Coord y, Elm_Xdnd_Action action EINA_UNUSED) 1764_drop_target_pos(void *data, Eo *obj, Evas_Coord x, Evas_Coord y, Elm_Xdnd_Action action EINA_UNUSED)
@@ -1459,9 +1770,9 @@ _drop_target_pos(void *data, Eo *obj, Evas_Coord x, Evas_Coord y, Elm_Xdnd_Actio
1459 Evas_Coord obj_x = 0, obj_y = 0; 1770 Evas_Coord obj_x = 0, obj_y = 0;
1460 /* If wdg == NULL, then canvas is a drop target or we have a error.*/ 1771 /* If wdg == NULL, then canvas is a drop target or we have a error.*/
1461 ERR("pointer: %d %d", x ,y); 1772 ERR("pointer: %d %d", x ,y);
1462 Gui_Session *session = (Gui_Session *) gui_context_editor_session_get(wdg_context_get(wdg));
1463 if (wdg) 1773 if (wdg)
1464 { 1774 {
1775 const Gui_Session *session = gui_context_editor_session_get(wdg_context_get(wdg));
1465 di = wdg_data_get(wdg_main_wdg_get(wdg), EDITOR_DND_DATA); 1776 di = wdg_data_get(wdg_main_wdg_get(wdg), EDITOR_DND_DATA);
1466 wdg_eo = session_eo_get(session, wdg); 1777 wdg_eo = session_eo_get(session, wdg);
1467 if (!IS_MAIN(wdg)) 1778 if (!IS_MAIN(wdg))
@@ -1490,7 +1801,7 @@ _drop_target_pos(void *data, Eo *obj, Evas_Coord x, Evas_Coord y, Elm_Xdnd_Actio
1490 { 1801 {
1491 Eo *child, *candidate = NULL; 1802 Eo *child, *candidate = NULL;
1492 int idx = 0; 1803 int idx = 0;
1493 if (di->packed) 1804 //if (di->packed)
1494 eo_do(wdg_eo, elm_obj_box_unpack(di->eo_cur)); 1805 eo_do(wdg_eo, elm_obj_box_unpack(di->eo_cur));
1495 Eina_List *box_chld = eo_do(wdg_eo, elm_obj_box_children_get()), *l; 1806 Eina_List *box_chld = eo_do(wdg_eo, elm_obj_box_children_get()), *l;
1496 di->box_pack_idx = 0; 1807 di->box_pack_idx = 0;
@@ -1639,6 +1950,10 @@ _drop_target_pos(void *data, Eo *obj, Evas_Coord x, Evas_Coord y, Elm_Xdnd_Actio
1639 iw = INT_GET(prop_value_nth_get(prop, 3)); 1950 iw = INT_GET(prop_value_nth_get(prop, 3));
1640 ih = INT_GET(prop_value_nth_get(prop, 4)); 1951 ih = INT_GET(prop_value_nth_get(prop, 4));
1641 dep_id = DEP_ID_GET(prop_value_nth_get(prop, 0)); 1952 dep_id = DEP_ID_GET(prop_value_nth_get(prop, 0));
1953 /* Don't pack widget which is currently dragged. */
1954 if (dnd_drag_wdg_get() == wdg_get(dep_id))
1955 continue;
1956 const Gui_Session *session = gui_context_editor_session_get(wdg_context_get(wdg));
1642 Eo *c = session_eo_get(session, wdg_get(dep_id)); 1957 Eo *c = session_eo_get(session, wdg_get(dep_id));
1643 eo_do(wdg_eo, elm_obj_table_pack_set(c, ix, iy, iw, ih)); 1958 eo_do(wdg_eo, elm_obj_table_pack_set(c, ix, iy, iw, ih));
1644 } 1959 }
@@ -1650,6 +1965,9 @@ _drop_target_pos(void *data, Eo *obj, Evas_Coord x, Evas_Coord y, Elm_Xdnd_Actio
1650 Gui_Widget_Property *prop = obj_container_item_prop_get(it); 1965 Gui_Widget_Property *prop = obj_container_item_prop_get(it);
1651 int ix, iy, iw, ih; 1966 int ix, iy, iw, ih;
1652 Dep_Id *dep_id = DEP_ID_GET(prop_value_nth_get(prop, 0)); 1967 Dep_Id *dep_id = DEP_ID_GET(prop_value_nth_get(prop, 0));
1968 if (dnd_drag_wdg_get() == wdg_get(dep_id))
1969 continue;
1970 const Gui_Session *session = gui_context_editor_session_get(wdg_context_get(wdg));
1653 Eo *c = session_eo_get(session, wdg_get(dep_id)); 1971 Eo *c = session_eo_get(session, wdg_get(dep_id));
1654 1972
1655 eo_do(wdg_eo, elm_obj_table_pack_get(c, &ix, &iy, &iw, &ih)); 1973 eo_do(wdg_eo, elm_obj_table_pack_get(c, &ix, &iy, &iw, &ih));
@@ -1689,6 +2007,74 @@ _drop_target_pos(void *data, Eo *obj, Evas_Coord x, Evas_Coord y, Elm_Xdnd_Actio
1689 2007
1690/*********************************************************/ 2008/*********************************************************/
1691 2009
2010/* This callback is called only when widget is dragged,
2011 * so wdg is not NULL. */
2012void
2013_drag_start_cb(const Gui_Widget *wdg, const Eo *_wdg_eo)
2014{
2015 Eo *wdg_eo = (Eo *) _wdg_eo;
2016 eo_do(wdg_eo, evas_obj_visibility_set(EINA_FALSE));
2017 Gui_Widget *wdg_container = NULL;
2018 Gui_Widget *wdg_parent = (Gui_Widget *) wdg_parent_get(wdg);
2019
2020 /* Unset selected widget. */
2021 _editor_wdg_selected_set(NULL);
2022
2023 const Gui_Session *session = gui_context_editor_session_get(wdg_context_get(wdg));
2024 if (!wdg_obj_container_item_get(wdg_parent, -1, wdg_name_get(wdg)))
2025 wdg_container = wdg_parent;
2026
2027 /* Explicitly call enter cb in order to create object, which will be dragged. */
2028 Evas_Coord x, y;
2029 if (IS_MAIN(wdg))
2030 {
2031 _drop_target_main_wdg_enter(NULL, egui_layout_gui_get()->main_win->canvas_bg);
2032 Main_Wdg_Info *wi = wdg_data_get(wdg, MAIN_WDG_INFO);
2033 Eo *fr = main_wdg_info_frame_get(wi);
2034 eo_do(fr, evas_obj_position_get(&x, &y));
2035 }
2036 else
2037 {
2038 _drop_target_main_wdg_enter((Gui_Widget *) wdg_main_wdg_get(wdg), NULL);
2039 eo_do(wdg_eo, evas_obj_position_get(&x, &y));
2040 }
2041 /* Unpack Eo object if dragging from container. */
2042 if (wdg_container)
2043 {
2044 Eo *wdg_cont_eo = session_eo_get(session, wdg_container);
2045
2046 if (!strcmp(wdg_class_name_get(wdg_container), DB_DEF_BOX_CLASS))
2047 {
2048 eo_do(wdg_cont_eo, elm_obj_box_unpack(wdg_eo));
2049 }
2050 else if (!strcmp(wdg_class_name_get(wdg_container), DB_DEF_TABLE_CLASS))
2051 {
2052 eo_do(wdg_cont_eo, elm_obj_table_unpack(wdg_eo));
2053 }
2054 /* Explicitly call target enter/pos cb, in order to calculate packing coords. */
2055 _drop_target_enter(wdg_container, NULL);
2056 _drop_target_pos(wdg_container, NULL, x, y, ELM_XDND_ACTION_UNKNOWN);
2057 }
2058 /* Case for main object. */
2059 else if (!wdg_parent)
2060 {
2061 _drop_target_pos(NULL, egui_layout_gui_get()->main_win->canvas_bg, x, y, ELM_XDND_ACTION_UNKNOWN);
2062
2063 Main_Wdg_Info *wi = wdg_data_get(wdg, MAIN_WDG_INFO);
2064 wdg_data_set(wdg, MAIN_WDG_INFO, NULL);
2065 if (wi)
2066 {
2067 Eo *fr = main_wdg_info_frame_get(wi);
2068 Eo *o = session_eo_get(session, wdg);
2069 Eo *optional_win = eo_do(o, eo_key_data_get("__editor_win"));
2070 //eo_do(fr, evas_obj_visibility_set(EINA_FALSE));
2071 eo_del(optional_win);
2072 eo_del(fr);
2073 free(wi);
2074 }
2075 }
2076}
2077
1692static Eina_Bool 2078static Eina_Bool
1693_widget_add(Gui_Session *session, const Gui_Widget *wdg, void *data) 2079_widget_add(Gui_Session *session, const Gui_Widget *wdg, void *data)
1694{ 2080{
@@ -1697,16 +2083,7 @@ _widget_add(Gui_Session *session, const Gui_Widget *wdg, void *data)
1697 Eo *o = _ffi_eo_add(session, wdg, NULL); 2083 Eo *o = _ffi_eo_add(session, wdg, NULL);
1698 if (!o) return EINA_FALSE; 2084 if (!o) return EINA_FALSE;
1699 evas_object_event_callback_add(o, EVAS_CALLBACK_KEY_DOWN, _key_down, wdg_context_get(wdg)); 2085 evas_object_event_callback_add(o, EVAS_CALLBACK_KEY_DOWN, _key_down, wdg_context_get(wdg));
1700 evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_DOWN, _mouse_down, wdg_context_get(wdg)); 2086
1701 //evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_UP, _mouse_up, NULL);
1702 eo_do(o, eo_event_callback_add(EVAS_OBJECT_EVENT_MOUSE_UP, _mouse_up, NULL));
1703 /* To avoid dragging box, when want to drag button. */
1704 evas_object_propagate_events_set(o, EINA_FALSE);
1705 /* Add callbacks to show widget resize arrows */
1706#if 0
1707 evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_IN, _mouse_in, NULL);
1708 evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_OUT, _mouse_out, NULL);
1709#endif
1710 eo_do(o, eo_event_callback_add(EVAS_OBJECT_EVENT_RESIZE, _wdg_resize, NULL)); 2087 eo_do(o, eo_event_callback_add(EVAS_OBJECT_EVENT_RESIZE, _wdg_resize, NULL));
1711 /* Add specific callbacks, related to UI. */ 2088 /* Add specific callbacks, related to UI. */
1712 session_eo_set(session, wdg, o); 2089 session_eo_set(session, wdg, o);
@@ -1802,6 +2179,8 @@ _widget_add(Gui_Session *session, const Gui_Widget *wdg, void *data)
1802 eo_do(fr, eo_key_data_set("winwdg", wdg, NULL)); 2179 eo_do(fr, eo_key_data_set("winwdg", wdg, NULL));
1803 } 2180 }
1804 fr = main_wdg_info_frame_get(wi); 2181 fr = main_wdg_info_frame_get(wi);
2182 evas_object_event_callback_add(iwin, EVAS_CALLBACK_MOUSE_DOWN, _mouse_down_main, wdg);
2183 evas_object_event_callback_add(iwin, EVAS_CALLBACK_MOUSE_UP, _mouse_up_main, wdg);
1805 2184
1806 DnD_Info *di = calloc (1, sizeof(DnD_Info)); 2185 DnD_Info *di = calloc (1, sizeof(DnD_Info));
1807 wdg_data_set(wdg, EDITOR_DND_DATA, di); 2186 wdg_data_set(wdg, EDITOR_DND_DATA, di);
@@ -2091,8 +2470,28 @@ _editor_undo(const Gui_Context *ctx)
2091 case MEMENTO_WIDGET_PARENT: 2470 case MEMENTO_WIDGET_PARENT:
2092 { 2471 {
2093 Dep_Id *wdg_id = gui_memento_wdg_get(memento); 2472 Dep_Id *wdg_id = gui_memento_wdg_get(memento);
2473 Gui_Widget *wdg = wdg_get(wdg_id);
2474 /* According to current scenario, widget can be dragged from another and dropped to canvas.
2475 * Thus here can be only main_wdg which is going to be undoed.
2476 * So it's frame and editor window must be deleted and Main_Wdg_Info data must be freed. */
2477 if (IS_MAIN(wdg) && !IS_WIN(wdg))
2478 {
2479 Gui_Session *session = (Gui_Session *) gui_context_editor_session_get(_active_context_get());
2480 Main_Wdg_Info *wi = wdg_data_get(wdg, MAIN_WDG_INFO);
2481 wdg_data_set(wdg, MAIN_WDG_INFO, NULL);
2482 if (wi)
2483 {
2484 Eo *fr = main_wdg_info_frame_get(wi);
2485 Eo *o = session_eo_get(session, wdg);
2486 Eo *optional_win = eo_do(o, eo_key_data_get("__editor_win"));
2487 //eo_do(fr, evas_obj_visibility_set(EINA_FALSE));
2488 eo_del(optional_win);
2489 eo_del(fr);
2490 free(wi);
2491 }
2492 }
2094 Dep_Id *old_parent_id = (Dep_Id *) gui_memento_old_pointer_get(memento); 2493 Dep_Id *old_parent_id = (Dep_Id *) gui_memento_old_pointer_get(memento);
2095 wdg_parent_set(wdg_get(wdg_id), dep_name_get(old_parent_id)); 2494 wdg_parent_set(wdg, dep_name_get(old_parent_id));
2096 break; 2495 break;
2097 } 2496 }
2098 case MEMENTO_ACTION: 2497 case MEMENTO_ACTION:
@@ -2276,8 +2675,28 @@ _editor_redo(const Gui_Context *ctx)
2276 case MEMENTO_WIDGET_PARENT: 2675 case MEMENTO_WIDGET_PARENT:
2277 { 2676 {
2278 Dep_Id *wdg_id = gui_memento_wdg_get(memento); 2677 Dep_Id *wdg_id = gui_memento_wdg_get(memento);
2678 Gui_Widget *wdg = wdg_get(wdg_id);
2679 /* According to current scenario, widget can be dragged from canvas and dropped into object.
2680 * Thus here can be only main_wdg which is going to be redoed.
2681 * So it's frame and editor window must be deleted and Main_Wdg_Info data must be freed. */
2682 if (IS_MAIN(wdg) && !IS_WIN(wdg))
2683 {
2684 Gui_Session *session = (Gui_Session *) gui_context_editor_session_get(_active_context_get());
2685 Main_Wdg_Info *wi = wdg_data_get(wdg, MAIN_WDG_INFO);
2686 wdg_data_set(wdg, MAIN_WDG_INFO, NULL);
2687 if (wi)
2688 {
2689 Eo *fr = main_wdg_info_frame_get(wi);
2690 Eo *o = session_eo_get(session, wdg);
2691 Eo *optional_win = eo_do(o, eo_key_data_get("__editor_win"));
2692 //eo_do(fr, evas_obj_visibility_set(EINA_FALSE));
2693 eo_del(optional_win);
2694 eo_del(fr);
2695 free(wi);
2696 }
2697 }
2279 Dep_Id *new_parent_id = (Dep_Id *) gui_memento_new_pointer_get(memento); 2698 Dep_Id *new_parent_id = (Dep_Id *) gui_memento_new_pointer_get(memento);
2280 wdg_parent_set(wdg_get(wdg_id), dep_name_get(new_parent_id)); 2699 wdg_parent_set(wdg, dep_name_get(new_parent_id));
2281 break; 2700 break;
2282 } 2701 }
2283 case MEMENTO_ACTION: 2702 case MEMENTO_ACTION:
@@ -3403,7 +3822,6 @@ _content_change_from_propview(void *data EINA_UNUSED, Eo *obj, const Eo_Event_De
3403 wdg_obj_container_unset((Gui_Widget *) prev_wdg_container); 3822 wdg_obj_container_unset((Gui_Widget *) prev_wdg_container);
3404 wdg_obj_container_set((Gui_Widget *) prev_wdg_container, _new_prev_container); 3823 wdg_obj_container_set((Gui_Widget *) prev_wdg_container, _new_prev_container);
3405 3824
3406
3407 /* Take old container's class name from content-property. */ 3825 /* Take old container's class name from content-property. */
3408 Object_Container_Item *_ci = wdg_obj_container_item_get(prev_wdg_container, -1, new_value); 3826 Object_Container_Item *_ci = wdg_obj_container_item_get(prev_wdg_container, -1, new_value);
3409 Gui_Widget_Property *old_prop = obj_container_item_prop_get(_ci); 3827 Gui_Widget_Property *old_prop = obj_container_item_prop_get(_ci);
diff --git a/src/lib/ffi_abstraction.c b/src/lib/ffi_abstraction.c
index 11e6935..48fbdcc 100644
--- a/src/lib/ffi_abstraction.c
+++ b/src/lib/ffi_abstraction.c
@@ -316,7 +316,7 @@ _ffi_eo_add(const Gui_Session *session, const Gui_Widget *wdg, Eo *parent_eo)
316 void (*func_pointer)() = NULL; 316 void (*func_pointer)() = NULL;
317 if (strcmp("eo_constructor", constr_id)) 317 if (strcmp("eo_constructor", constr_id))
318 { 318 {
319 ERR("only Eo Constructor supported in ffi!"); 319 ERR("only Eo Constructor supported in ffi! Got: %s", constr_id);
320 exit(1); 320 exit(1);
321 } 321 }
322 else 322 else
@@ -327,7 +327,7 @@ _ffi_eo_add(const Gui_Session *session, const Gui_Widget *wdg, Eo *parent_eo)
327 /* Provide values with parent object. 327 /* Provide values with parent object.
328 * If parent name is NULL, where is no parent obj. */ 328 * If parent name is NULL, where is no parent obj. */
329 parent_wdg = wdg_parent_get(wdg); 329 parent_wdg = wdg_parent_get(wdg);
330 if (parent_wdg) 330 if (parent_wdg && !parent_eo)
331 { 331 {
332 parent_eo = session_eo_get(session, parent_wdg); 332 parent_eo = session_eo_get(session, parent_wdg);
333 if (!parent_eo) 333 if (!parent_eo)
diff --git a/src/lib/gui_widget.c b/src/lib/gui_widget.c
index 311998e..76878a2 100644
--- a/src/lib/gui_widget.c
+++ b/src/lib/gui_widget.c
@@ -1594,6 +1594,17 @@ wdg_obj_container_item_remove(const Gui_Widget *wdg, Object_Container_Item *ci)
1594 } 1594 }
1595} 1595}
1596 1596
1597void
1598wdg_obj_container_item_remove_all(const Gui_Widget *wdg)
1599{
1600 Object_Container_Item *it;
1601 Eina_List *lst = wdg_obj_container_contents_list_get(wdg), *l, *l2;
1602 EINA_LIST_FOREACH_SAFE(lst, l, l2, it)
1603 {
1604 wdg_obj_container_item_remove(wdg, it);
1605 }
1606}
1607
1597/************************************************************/ 1608/************************************************************/
1598 1609
1599static void 1610static void
diff --git a/src/lib/gui_widget.h b/src/lib/gui_widget.h
index fd656f2..4440913 100644
--- a/src/lib/gui_widget.h
+++ b/src/lib/gui_widget.h
@@ -263,10 +263,18 @@ gui_context_data_get(const Gui_Context *ctx, const char *key);
263void 263void
264gui_context_editor_session_set(Gui_Context *ctx, const Gui_Session *session); 264gui_context_editor_session_set(Gui_Context *ctx, const Gui_Session *session);
265 265
266/* Det editor session from the context. */ 266/* Get editor session from the context. */
267const Gui_Session* 267const Gui_Session*
268gui_context_editor_session_get(const Gui_Context *ctx); 268gui_context_editor_session_get(const Gui_Context *ctx);
269 269
270/* Save dnd session into the context. */
271void
272gui_context_dnd_session_set(Gui_Context *ctx, const Gui_Session *session);
273
274/* Get dnd session from the context. */
275const Gui_Session*
276gui_context_dnd_session_get(const Gui_Context *ctx);
277
270/* Add simulate session into the list of simulate sessions in progress*/ 278/* Add simulate session into the list of simulate sessions in progress*/
271void 279void
272gui_context_simulate_session_add(Gui_Context *ctx, const Gui_Session *session); 280gui_context_simulate_session_add(Gui_Context *ctx, const Gui_Session *session);
@@ -445,6 +453,9 @@ wdg_obj_container_item_add(const Gui_Widget *wdg, Object_Container_Item *ci, int
445void 453void
446wdg_obj_container_item_remove(const Gui_Widget *wdg, Object_Container_Item *ci); 454wdg_obj_container_item_remove(const Gui_Widget *wdg, Object_Container_Item *ci);
447 455
456void
457wdg_obj_container_item_remove_all(const Gui_Widget *wdg);
458
448const char* 459const char*
449wdg_obj_container_class_name_get(const Gui_Widget *wdg); 460wdg_obj_container_class_name_get(const Gui_Widget *wdg);
450 461