billiob pushed a commit to branch master. http://git.enlightenment.org/apps/terminology.git/commit/?id=496a307f6720429de7999da4cb00aac173ed0226
commit 496a307f6720429de7999da4cb00aac173ed0226 Author: Boris Faure <[email protected]> Date: Sat Feb 29 16:18:07 2020 +0100 win: drag a tab to split --- src/bin/term_container.h | 12 +++ src/bin/win.c | 275 ++++++++++++++++++++++++++++++++++++----------- 2 files changed, 222 insertions(+), 65 deletions(-) diff --git a/src/bin/term_container.h b/src/bin/term_container.h index 81cb06b..47b801d 100644 --- a/src/bin/term_container.h +++ b/src/bin/term_container.h @@ -27,6 +27,14 @@ typedef enum _Term_Container_Type TERM_CONTAINER_TYPE_WIN } Term_Container_Type; +typedef enum _Split_Direction { + SPLIT_DIRECTION_NONE, + SPLIT_DIRECTION_LEFT, + SPLIT_DIRECTION_RIGHT, + SPLIT_DIRECTION_TOP, + SPLIT_DIRECTION_BOTTOM, +} Split_Direction; + struct _Term_Container { Term_Container_Type type; Term_Container *parent; @@ -49,6 +57,10 @@ struct _Term_Container { Evas_Coord mx, Evas_Coord my); void (*split)(Term_Container *tc, Term_Container *child, Term *from, const char *cmd, Eina_Bool is_horizontal); + int (*split_direction)(Term_Container *tc, + Term_Container *child_orig, + Term_Container *child_new, + Split_Direction direction); void (*size_eval)(Term_Container *container, Sizeinfo *info); void (*swallow)(Term_Container *container, Term_Container *orig, Term_Container *new_child); diff --git a/src/bin/win.c b/src/bin/win.c index 704eb6b..3cc2eb9 100644 --- a/src/bin/win.c +++ b/src/bin/win.c @@ -73,24 +73,17 @@ typedef struct _Tabs Tabs; typedef struct _Tab_Item Tab_Item; typedef struct _Tab_Drag Tab_Drag; -enum drag_over_position { - DRAG_OVER_NONE, - DRAG_OVER_LEFT, - DRAG_OVER_RIGHT, - DRAG_OVER_TOP, - DRAG_OVER_BOTTOM, -}; struct _Tab_Drag { Evas_Coord mdx; /* Mouse-down x */ Evas_Coord mdy; /* Mouse-down y */ - enum drag_over_position drag_over; + Split_Direction split_direction; Term *term_over; + Term *term; Evas_Object *icon; Evas *e; Ecore_Timer *timer; - Term *term; }; struct _Tabbar @@ -470,6 +463,15 @@ _solo_split(Term_Container *tc, tc->parent->split(tc->parent, tc, from, cmd, is_horizontal); } +static int +_solo_split_direction(Term_Container *tc, + Term_Container *child_orig EINA_UNUSED, + Term_Container *child_new, + Split_Direction direction) +{ + return tc->parent->split_direction(tc->parent, tc, child_new, direction); +} + static Term * _solo_term_next(const Term_Container *tc, const Term_Container *_child EINA_UNUSED) @@ -780,6 +782,7 @@ _solo_new(Term *term, Win *wn) tc->focused_term_get = _solo_focused_term_get; tc->get_evas_object = _solo_get_evas_object; tc->split = _solo_split; + tc->split_direction = _solo_split_direction; tc->find_term_at_coords = _solo_find_term_at_coords; tc->size_eval = _solo_size_eval; tc->swallow = NULL; @@ -1410,13 +1413,66 @@ _win_split(Term_Container *tc, Term_Container *child, _solo_title_show(tc_solo_new); } + tc_split->focus(tc_split, tc_solo_new); tc_split->is_focused = tc->is_focused; tc->swallow(tc, NULL, tc_split); } else { - DBG("term is not splittable"); + ERR("term is not splittable"); + } +} + +static int +_win_split_direction(Term_Container *tc, + Term_Container *child_orig, + Term_Container *child_new, + Split_Direction direction) +{ + Term_Container *child1, *child2, *tc_split; + Win *wn; + Eina_Bool is_horizontal = + (direction == SPLIT_DIRECTION_LEFT) || (direction == SPLIT_DIRECTION_RIGHT) ? + EINA_FALSE : EINA_TRUE; + + assert (tc->type == TERM_CONTAINER_TYPE_WIN); + wn = (Win*) tc; + + if (!_term_container_is_splittable(tc, is_horizontal)) + { + ERR("term is not splittable"); + return -1; + } + + if ((direction == SPLIT_DIRECTION_TOP) || + (direction == SPLIT_DIRECTION_LEFT)) + { + child1 = child_new; + child2 = child_orig; + } + else + { + child1 = child_orig; + child2 = child_new; + } + tc_split = _split_new(child1, child2, is_horizontal); + + if (wn->config->show_tabs) + { + if (child_orig->type == TERM_CONTAINER_TYPE_SOLO) + { + _solo_title_show(child_orig); + } + _solo_title_show(child_new); } + + tc_split->is_focused = tc->is_focused; + tc->swallow(tc, NULL, tc_split); + + child_orig->unfocus(child_orig, tc); + child_new->focus(child_new, tc_split); + + return 0; } static void @@ -1971,6 +2027,7 @@ win_new(const char *name, const char *role, const char *title, tc->focused_term_get = _win_focused_term_get; tc->get_evas_object = _win_get_evas_object; tc->split = _win_split; + tc->split_direction = _win_split_direction; tc->find_term_at_coords = _win_find_term_at_coords; tc->size_eval = _win_size_eval; tc->swallow = _win_swallow; @@ -2641,6 +2698,7 @@ _split_split(Term_Container *tc, Term_Container *child, obj_split = tc_split->get_evas_object(tc_split); + tc_split->focus(tc_split, tc_solo_new); tc_split->is_focused = tc->is_focused; tc->swallow(tc, child, tc_split); @@ -2652,6 +2710,66 @@ _split_split(Term_Container *tc, Term_Container *child, evas_object_show(obj_split); } +static int +_split_split_direction(Term_Container *tc, + Term_Container *child_orig, + Term_Container *child_new, + Split_Direction direction) +{ + Split *split; + Win *wn; + Term_Container *child1, *child2, *tc_split; + Eina_Bool is_horizontal = + (direction == SPLIT_DIRECTION_LEFT) || (direction == SPLIT_DIRECTION_RIGHT) ? + EINA_FALSE : EINA_TRUE; + + assert (tc->type == TERM_CONTAINER_TYPE_SPLIT); + split = (Split *)tc; + wn = tc->wn; + + if (!_term_container_is_splittable(tc, is_horizontal)) + { + ERR("term is not splittable"); + return -1; + } + + if ((direction == SPLIT_DIRECTION_TOP) || + (direction == SPLIT_DIRECTION_LEFT)) + { + child1 = child_new; + child2 = child_orig; + } + else + { + child1 = child_orig; + child2 = child_new; + } + + if (child_orig == split->tc1) + elm_object_part_content_unset(split->panes, PANES_TOP); + else + elm_object_part_content_unset(split->panes, PANES_BOTTOM); + + tc_split = _split_new(child1, child2, is_horizontal); + + if (wn->config->show_tabs) + { + if (child_orig->type == TERM_CONTAINER_TYPE_SOLO) + { + _solo_title_show(child_orig); + } + _solo_title_show(child_new); + } + + tc_split->is_focused = tc->is_focused; + tc->swallow(tc, child_orig, tc_split); + + child_orig->unfocus(child_orig, tc); + child_new->focus(child_new, tc_split); + + return 0; +} + static Eina_Bool _split_is_visible(Term_Container *tc, Term_Container *_child EINA_UNUSED) { @@ -2670,7 +2788,6 @@ _split_detach(Term_Container *tc, Term_Container *solo_child) _split_close(tc, solo_child); } -/* tc1 is a new solo */ static Term_Container * _split_new(Term_Container *tc1, Term_Container *tc2, Eina_Bool is_horizontal) @@ -2697,6 +2814,7 @@ _split_new(Term_Container *tc1, Term_Container *tc2, tc->focused_term_get = _split_focused_term_get; tc->get_evas_object = _split_get_evas_object; tc->split = _split_split; + tc->split_direction = _split_split_direction; tc->find_term_at_coords = _split_find_term_at_coords; tc->size_eval = _split_size_eval; tc->swallow = _split_swallow; @@ -2719,14 +2837,7 @@ _split_new(Term_Container *tc1, Term_Container *tc2, split->tc1 = tc1; split->tc2 = tc2; - if (tc1->is_focused) - { - tc1->unfocus(tc1, tc); - tc2->focus(tc2, tc); - split->last_focus = tc2; - } - else - split->last_focus = tc1; + split->last_focus = tc1; o = split->panes = elm_panes_add(tc1->wn->win); elm_object_style_set(o, "flush"); @@ -2977,24 +3088,24 @@ static void _tab_drag_disable_anim_over(void) { if ((!_tab_drag) || (!_tab_drag->term_over) || - (_tab_drag->drag_over == DRAG_OVER_NONE)) + (_tab_drag->split_direction == SPLIT_DIRECTION_NONE)) return; - switch (_tab_drag->drag_over) + switch (_tab_drag->split_direction) { - case DRAG_OVER_LEFT: + case SPLIT_DIRECTION_LEFT: elm_layout_signal_emit(_tab_drag->term_over->bg, "drag_left,off", "terminology"); break; - case DRAG_OVER_RIGHT: + case SPLIT_DIRECTION_RIGHT: elm_layout_signal_emit(_tab_drag->term_over->bg, "drag_right,off", "terminology"); break; - case DRAG_OVER_TOP: + case SPLIT_DIRECTION_TOP: elm_layout_signal_emit(_tab_drag->term_over->bg, "drag_top,off", "terminology"); break; - case DRAG_OVER_BOTTOM: + case SPLIT_DIRECTION_BOTTOM: elm_layout_signal_emit(_tab_drag->term_over->bg, "drag_bottom,off", "terminology"); break; @@ -3119,13 +3230,11 @@ _term_on_horizontal_drag(void *data, } static void -_tab_drag_reinsert(Term *term, Evas_Coord mx, Evas_Coord my) +_tab_drag_reinsert(Term *term, double mid) { - Evas_Coord x = 0, y = 0, w = 0, h = 0, off_x = 0, off_y = 0; Term_Container *tc = term->container; Term_Container *tc_parent = tc->parent; Tabs *tabs; - double mid; tc = term->container; assert (tc->type == TERM_CONTAINER_TYPE_SOLO); @@ -3135,18 +3244,6 @@ _tab_drag_reinsert(Term *term, Evas_Coord mx, Evas_Coord my) tabs = (Tabs*) tc_parent; - evas_object_geometry_get(term->bg_edj, &off_x, &off_y, NULL, NULL); - edje_object_part_geometry_get(term->bg_edj, "tabdrag", - &x, NULL, &w, NULL); - edje_object_part_geometry_get(term->bg_edj, "tabmiddle", - NULL, &y, NULL, &h); - x += off_x; - y += off_y; - - if (!ELM_RECTS_INTERSECT(x,y,w,h, mx,my,1,1)) - return; - - mid = (double)(mx - x) / (double)w; edje_object_part_drag_value_set(term->bg_edj, "terminology.tabl", mid, 0.0); edje_object_part_drag_value_set(term->bg_edj, "terminology.tabr", mid, 0.0); @@ -3216,23 +3313,49 @@ _tab_reorg(Term *term, Term *to_term, Evas_Coord mx, Evas_Coord my) assert(tc_orig->type == TERM_CONTAINER_TYPE_SOLO); assert(to_tc->type == TERM_CONTAINER_TYPE_SOLO); - tc_orig_parent->detach(tc_orig_parent, tc_orig); - _solo_attach(to_tc, tc_orig); + if (_tab_drag->split_direction == SPLIT_DIRECTION_NONE) + { + Evas_Coord x = 0, y = 0, w = 0, h = 0, off_x = 0, off_y = 0; + double mid; + + /* check whether there is a need to add a tab or fail the drag */ + evas_object_geometry_get(term->bg_edj, &off_x, &off_y, NULL, NULL); + edje_object_part_geometry_get(term->bg_edj, "tabdrag", + &x, NULL, &w, NULL); + edje_object_part_geometry_get(term->bg_edj, "tabmiddle", + NULL, &y, NULL, &h); + if (!ELM_RECTS_INTERSECT(x,y,w,h, mx,my,1,1)) + return; + + mid = (double)(mx - x) / (double)w; - /* reinsert at correct place */ - _tab_drag_reinsert(term, mx, my); + tc_orig_parent->detach(tc_orig_parent, tc_orig); + _solo_attach(to_tc, tc_orig); + + /* reinsert at correct place */ + _tab_drag_reinsert(term, mid); + return; + } + + tc_orig_parent->detach(tc_orig_parent, tc_orig); + to_tc->split_direction(to_tc, to_tc, tc_orig, _tab_drag->split_direction); } static void -_tab_drag_stop(Term *term) +_tab_drag_stop(void) { Evas_Coord mx = 0, my = 0; - Win *wn = term->wn; - Term_Container *tc_wn = (Term_Container*) wn; + Win *wn; + Term_Container *tc_wn; + Term *term; Term *term_at_coords; assert(_tab_drag); + term = _tab_drag->term; + wn = term->wn; + tc_wn = (Term_Container*) wn; + evas_pointer_canvas_xy_get(_tab_drag->e, &mx, &my); term_at_coords = tc_wn->find_term_at_coords(tc_wn, mx, my); if (!term_at_coords) @@ -3240,8 +3363,20 @@ _tab_drag_stop(Term *term) if (term_at_coords == term) { + Evas_Coord x = 0, y = 0, w = 0, h = 0, off_x = 0, off_y = 0; + double mid; + /* Reinsert in same set of Tabs or same "tab" (could be a split) */ - _tab_drag_reinsert(term, mx, my); + evas_object_geometry_get(term->bg_edj, &off_x, &off_y, NULL, NULL); + edje_object_part_geometry_get(term->bg_edj, "tabdrag", + &x, NULL, &w, NULL); + edje_object_part_geometry_get(term->bg_edj, "tabmiddle", + NULL, &y, NULL, &h); + if (!ELM_RECTS_INTERSECT(x,y,w,h, mx,my,1,1)) + goto end; + + mid = (double)(mx - x) / (double)w; + _tab_drag_reinsert(term, mid); } else { @@ -3262,9 +3397,9 @@ _term_on_drag_stop(void *data, Term *term = data; Term_Container *tc; - if (_tab_drag && _tab_drag->term == term && _tab_drag->icon) + if (_tab_drag && _tab_drag->icon) { - _tab_drag_stop(term); + _tab_drag_stop(); return; } _tab_drag_free(); @@ -3296,7 +3431,7 @@ _tabs_drag_mouse_move( Win *wn; Term_Container *tc_wn; Term *term_at_coords; - enum drag_over_position drag_over_position = DRAG_OVER_NONE; + Split_Direction split_direction = SPLIT_DIRECTION_NONE; if (!_tab_drag || !_tab_drag->icon) return; @@ -3318,56 +3453,56 @@ _tabs_drag_mouse_move( &x, &y, &w, &h); if (ELM_RECTS_INTERSECT(x+off_x, y+off_y, w, h, mx, my, 1, 1)) { - drag_over_position = DRAG_OVER_LEFT; + split_direction = SPLIT_DIRECTION_LEFT; goto found; } edje_object_part_geometry_get(term_at_coords->bg_edj, "drag_right_outline", &x, &y, &w, &h); if (ELM_RECTS_INTERSECT(x+off_x, y+off_y, w, h, mx, my, 1, 1)) { - drag_over_position = DRAG_OVER_RIGHT; + split_direction = SPLIT_DIRECTION_RIGHT; goto found; } edje_object_part_geometry_get(term_at_coords->bg_edj, "drag_top_outline", &x, &y, &w, &h); if (ELM_RECTS_INTERSECT(x+off_x, y+off_y, w, h, mx, my, 1, 1)) { - drag_over_position = DRAG_OVER_TOP; + split_direction = SPLIT_DIRECTION_TOP; goto found; } edje_object_part_geometry_get(term_at_coords->bg_edj, "drag_bottom_outline", &x, &y, &w, &h); if (ELM_RECTS_INTERSECT(x+off_x, y+off_y, w, h, mx, my, 1, 1)) { - drag_over_position = DRAG_OVER_BOTTOM; + split_direction = SPLIT_DIRECTION_BOTTOM; goto found; } found: if ((_tab_drag->term_over != NULL) && ((_tab_drag->term_over != term_at_coords) || - (_tab_drag->drag_over != drag_over_position))) + (_tab_drag->split_direction != split_direction))) { _tab_drag_disable_anim_over(); } - if ((drag_over_position != DRAG_OVER_NONE) && + if ((split_direction != SPLIT_DIRECTION_NONE) && ((_tab_drag->term_over != term_at_coords) || - (_tab_drag->drag_over != drag_over_position))) + (_tab_drag->split_direction != split_direction))) { - switch (drag_over_position) + switch (split_direction) { - case DRAG_OVER_LEFT: + case SPLIT_DIRECTION_LEFT: elm_layout_signal_emit(term_at_coords->bg, "drag_left,on", "terminology"); break; - case DRAG_OVER_RIGHT: + case SPLIT_DIRECTION_RIGHT: elm_layout_signal_emit(term_at_coords->bg, "drag_right,on", "terminology"); break; - case DRAG_OVER_TOP: + case SPLIT_DIRECTION_TOP: elm_layout_signal_emit(term_at_coords->bg, "drag_top,on", "terminology"); break; - case DRAG_OVER_BOTTOM: + case SPLIT_DIRECTION_BOTTOM: elm_layout_signal_emit(term_at_coords->bg, "drag_bottom,on", "terminology"); break; @@ -3376,7 +3511,7 @@ _tabs_drag_mouse_move( } } _tab_drag->term_over = term_at_coords; - _tab_drag->drag_over = drag_over_position; + _tab_drag->split_direction = split_direction; } static Eina_Bool @@ -4647,6 +4782,15 @@ _tabs_split(Term_Container *tc, tc->parent->split(tc->parent, tc, from, cmd, is_horizontal); } +static int +_tabs_split_direction(Term_Container *tc, + Term_Container *child_orig EINA_UNUSED, + Term_Container *child_new, + Split_Direction direction) +{ + return tc->parent->split_direction(tc->parent, tc, child_new, direction); +} + static Eina_Bool _tabs_is_visible(Term_Container *tc, Term_Container *child) { @@ -4694,6 +4838,7 @@ _tabs_new(Term_Container *child, Term_Container *parent) tc->focused_term_get = _tabs_focused_term_get; tc->get_evas_object = _tabs_get_evas_object; tc->split = _tabs_split; + tc->split_direction = _tabs_split_direction; tc->find_term_at_coords = _tabs_find_term_at_coords; tc->size_eval = _tabs_size_eval; tc->swallow = _tabs_swallow; @@ -6321,7 +6466,7 @@ _term_free(Term *term) if (_tab_drag && _tab_drag->term_over == term) { _tab_drag->term_over = NULL; - _tab_drag->drag_over = DRAG_OVER_NONE; + _tab_drag->split_direction = SPLIT_DIRECTION_NONE; } if (term->sendfile_request) { --
