diff --git a/ChangeLog.theme b/ChangeLog.theme index 71868a92..4b731079 100644 --- a/ChangeLog.theme +++ b/ChangeLog.theme @@ -18,6 +18,12 @@ Changes since 1.6.0: the current tab is dragged outside of the tabbar. * In group "terminology/background", parts "tabdrag", "tabmiddle" are used to adjust drag. + * In group "terminology/background", parts "drag_left_outline", + "drag_right_outline", "drag_top_outline", "drag_bottom_outline" are used to + know when the cursor enters them when dragging a tab into them. + * In group "terminology/background", signals "drag_left,on", "drag_left,off" + are received when the mouse enters or leaves "drag_left_outline". Same for + right, top, bottom. Changes since 1.5.0: -------------------- diff --git a/THEME.md b/THEME.md index 7c4f7cbc..bf3436c2 100644 --- a/THEME.md +++ b/THEME.md @@ -61,11 +61,20 @@ Here is swallowed an object of group `terminology.background`. ### `tabdrag` and `tabmiddle` Their geometry are used to adjust drag values. +### `drag_left_outline`, `drag_right_outline`, `drag_top_outline`, `drag_bottom_outline` +Their geometry are used to know when the cursor enters them when dragging a +tab. + ## Signal received ### `tabbar,off` and `tabbar,on` Whether to display a tab bar. Default is off. ### `tab_btn,off` and `tab_btn,on` Whether to display a tab button to easily navigate through tabs. Default is off. +### `drag_left,on`, `drag_right,on`, `drag_top,on`, `drag_bottom,on` +When to start an animation when the cursor enters `drag_XXXX_outline` while +dragging a tab. +### `drag_left,off`, `drag_right,off`, `drag_top,off`, `drag_bottom,off` +When to stop an animation started by the related `*,on` signals. ### TODO diff --git a/data/themes/default/background.edc b/data/themes/default/background.edc index c450730c..176ae089 100644 --- a/data/themes/default/background.edc +++ b/data/themes/default/background.edc @@ -1373,11 +1373,35 @@ group { name: "terminology/background"; signal: "hdrag,on"; source: "terminology"; action: STATE_SET "default" 0.0; target: "tabdrag"; + target: "drag_left_pulse"; + target: "drag_left_outline"; + target: "drag_left_glow"; + target: "drag_right_pulse"; + target: "drag_right_outline"; + target: "drag_right_glow"; + target: "drag_top_pulse"; + target: "drag_top_outline"; + target: "drag_top_glow"; + target: "drag_bottom_pulse"; + target: "drag_bottom_outline"; + target: "drag_bottom_glow"; } program { signal: "hdrag,off"; source: "terminology"; action: STATE_SET "hdrag,off" 0.0; target: "tabdrag"; + target: "drag_left_pulse"; + target: "drag_left_outline"; + target: "drag_left_glow"; + target: "drag_right_pulse"; + target: "drag_right_outline"; + target: "drag_right_glow"; + target: "drag_top_pulse"; + target: "drag_top_outline"; + target: "drag_top_glow"; + target: "drag_bottom_pulse"; + target: "drag_bottom_outline"; + target: "drag_bottom_glow"; } // left boundary of the active tab (dragable 0.0 -> 1.0) part { name: "terminology.tabl"; type: SPACER; @@ -1439,8 +1463,8 @@ group { name: "terminology/background"; align: 0.5 0.5; rel1.to_x: "tab_bevel_top2"; rel1.to_y: "tabmiddle"; - rel2.to_y: "tabmiddle"; rel2.to_x: "tabclose"; + rel2.to_y: "tabmiddle"; rel2.relative: 0.5 1.0; visible: 0; fixed: 1 1; @@ -1607,7 +1631,6 @@ group { name: "terminology/background"; } } } - program { signal: "mouse,down,1,double"; source: "tabmiddle"; action: SIGNAL_EMIT "tab,title" "terminology"; @@ -1763,6 +1786,141 @@ group { name: "terminology/background"; target: "bell_strobe"; } + #define DRAG_TARGET(DIR, REL_ONE, REL_TWO) \ + part { name: "drag_"##DIR##"_pulse"; \ + mouse_events: 0; \ + description { state: "default" 0.0; \ + rel1.offset: -4 -4; \ + rel1.to: "drag_"##DIR##"_outline"; \ + rel2.offset: 3 3; \ + rel2.to: "drag_"##DIR##"_outline"; \ + image { \ + normal: "cr_pulse.png"; \ + border: 4 4 4 4; \ + } \ + color: 51 153 255 0; \ + visible: 0; \ + } \ + description { state: "hdrag,off" 0.0; \ + inherit: "default" 0.0; \ + } \ + description { state: "on" 0.0; \ + inherit: "default" 0.0; \ + color: 51 153 255 255; \ + visible: 1; \ + } \ + description { state: "out" 0.0; \ + inherit: "default" 0.0; \ + color: 51 153 255 0; \ + rel1.offset: -8 -8; \ + rel2.offset: 7 7; \ + visible: 1; \ + } \ + } \ + part { name: "drag_"##DIR##"_glow"; \ + mouse_events: 0; \ + description { state: "default" 0.0; \ + rel1.offset: -4 -4; \ + rel1.to: "drag_"##DIR##"_outline"; \ + rel2.offset: 3 3; \ + rel2.to: "drag_"##DIR##"_outline"; \ + image { \ + normal: "cr_glow.png"; \ + border: 9 9 9 9; \ + } \ + color: 51 153 255 40; \ + visible: 0; \ + } \ + description { state: "hdrag,off" 0.0; \ + inherit: "default" 0.0; \ + visible: 1; \ + } \ + description { state: "active" 0.0; \ + inherit: "default" 0.0; \ + color: 51 153 255 255; \ + visible: 1; \ + } \ + } \ + part { name: "drag_"##DIR##"_outline"; \ + mouse_events: 0; \ + description { state: "default" 0.0; \ + rel1.to: "viewregion"; \ + rel1.relative: REL_ONE; \ + rel2.to: "viewregion"; \ + rel2.relative: REL_TWO; \ + image { \ + normal: "cr_out.png"; \ + border: 3 3 3 3; \ + } \ + color: 51 153 255 80; \ + visible: 0; \ + } \ + description { state: "hdrag,off" 0.0; \ + inherit: "default" 0.0; \ + visible: 1; \ + } \ + description { state: "active" 0.0; \ + inherit: "default" 0.0; \ + color: 255 255 255 255; \ + visible: 1; \ + } \ + } \ + program { \ + name: "drag_"##DIR##",on"; \ + signal: "drag_"##DIR##",on"; source: "terminology"; \ + action: STATE_SET "active" 0.0; \ + target: "drag_"##DIR##"_glow"; \ + target: "drag_"##DIR##"_outline"; \ + after: "drag_"##DIR##",on2"; \ + after: "drag_"##DIR##"_pulse"; \ + } \ + program { name: "drag_"##DIR##",on2"; \ + in: 0.5 0.0; \ + action: STATE_SET "default" 0.0; \ + transition: DECELERATE 0.2; \ + target: "drag_"##DIR##"_glow"; \ + target: "drag_"##DIR##"_outline"; \ + after: "drag_"##DIR##",on3"; \ + } \ + program { name: "drag_"##DIR##",on3"; \ + in: 0.5 0.0; \ + action: STATE_SET "active" 0.0; \ + target: "drag_"##DIR##"_glow"; \ + target: "drag_"##DIR##"_outline"; \ + after: "drag_"##DIR##",on2"; \ + after: "drag_"##DIR##"_pulse"; \ + } \ + program { name: "drag_"##DIR##"_pulse"; \ + action: STATE_SET "on" 0.0; \ + target: "drag_"##DIR##"_pulse"; \ + after: "drag_"##DIR##"_pulse2"; \ + } \ + program { name: "drag_"##DIR##"_pulse2"; \ + action: STATE_SET "out" 0.0; \ + transition: DECELERATE 0.4; \ + target: "drag_"##DIR##"_pulse"; \ + } \ + program { \ + signal: "drag_"##DIR##",off"; source: "terminology"; \ + action: ACTION_STOP; \ + target: "drag_"##DIR##",on"; \ + target: "drag_"##DIR##",on2"; \ + target: "drag_"##DIR##",on3"; \ + target: "drag_"##DIR##"_pulse"; \ + target: "drag_"##DIR##"_pulse2"; \ + after: "drag_"##DIR##",off2"; \ + } \ + program { name: "drag_"##DIR##",off2"; \ + action: STATE_SET "default" 0.0; \ + target: "drag_"##DIR##"_glow"; \ + target: "drag_"##DIR##"_outline"; \ + } + + DRAG_TARGET(left, 0.0 0.2, 0.15 0.8) + DRAG_TARGET(right, 0.85 0.2, 1.0 0.8) + DRAG_TARGET(top, 0.2 0.0, 0.8 0.2) + DRAG_TARGET(bottom, 0.2 0.8, 0.8 1.0) + //////////////////////////////////////////////////////////////////// // popup media over the terminal (until dismissed) part { name: "popmedia_clip"; type: RECT; diff --git a/src/bin/win.c b/src/bin/win.c index 5e92190a..704eb6b3 100644 --- a/src/bin/win.c +++ b/src/bin/win.c @@ -73,10 +73,20 @@ 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; + Term *term_over; Evas_Object *icon; Evas *e; Ecore_Timer *timer; @@ -2963,12 +2973,46 @@ _term_hdrag_off(Term *term, void *data EINA_UNUSED) return ECORE_CALLBACK_PASS_ON; } +static void +_tab_drag_disable_anim_over(void) +{ + if ((!_tab_drag) || (!_tab_drag->term_over) || + (_tab_drag->drag_over == DRAG_OVER_NONE)) + return; + + switch (_tab_drag->drag_over) + { + case DRAG_OVER_LEFT: + elm_layout_signal_emit(_tab_drag->term_over->bg, + "drag_left,off", "terminology"); + break; + case DRAG_OVER_RIGHT: + elm_layout_signal_emit(_tab_drag->term_over->bg, + "drag_right,off", "terminology"); + break; + case DRAG_OVER_TOP: + elm_layout_signal_emit(_tab_drag->term_over->bg, + "drag_top,off", "terminology"); + break; + case DRAG_OVER_BOTTOM: + elm_layout_signal_emit(_tab_drag->term_over->bg, + "drag_bottom,off", "terminology"); + break; + default: + break; + } + elm_layout_signal_emit(_tab_drag->term_over->bg, + "hdrag,off", "terminology"); +} + + static void _tab_drag_free(void) { if (!_tab_drag) return; + _tab_drag_disable_anim_over(); for_each_term_do(_tab_drag->term->wn, &_term_hdrag_on, NULL); ecore_timer_del(_tab_drag->timer); @@ -3248,18 +3292,91 @@ _tabs_drag_mouse_move( const char *emission EINA_UNUSED, const char *source EINA_UNUSED) { - int x, y, w, h; - Evas_Coord xm, ym; + Evas_Coord x, y, w, h, off_x, off_y, mx, my; + Win *wn; + Term_Container *tc_wn; + Term *term_at_coords; + enum drag_over_position drag_over_position = DRAG_OVER_NONE; if (!_tab_drag || !_tab_drag->icon) return; + wn = _tab_drag->term->wn; + tc_wn = (Term_Container*) wn; + evas_object_geometry_get(_tab_drag->icon, NULL, NULL, &w, &h); - evas_pointer_canvas_xy_get(_tab_drag->e, &xm, &ym); - x = (xm - (w/2)); - y = (ym - (h/2)); + evas_pointer_canvas_xy_get(_tab_drag->e, &mx, &my); + x = (mx - (w/2)); + y = (my - (h/2)); evas_object_move(_tab_drag->icon, x, y); - /* TODO: boris */ + + term_at_coords = tc_wn->find_term_at_coords(tc_wn, mx, my); + if (!term_at_coords) + return; + evas_object_geometry_get(term_at_coords->bg_edj, &off_x, &off_y, NULL, NULL); + edje_object_part_geometry_get(term_at_coords->bg_edj, "drag_left_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_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; + 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; + 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; + 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_disable_anim_over(); + } + if ((drag_over_position != DRAG_OVER_NONE) && + ((_tab_drag->term_over != term_at_coords) || + (_tab_drag->drag_over != drag_over_position))) + { + switch (drag_over_position) + { + case DRAG_OVER_LEFT: + elm_layout_signal_emit(term_at_coords->bg, + "drag_left,on", "terminology"); + break; + case DRAG_OVER_RIGHT: + elm_layout_signal_emit(term_at_coords->bg, + "drag_right,on", "terminology"); + break; + case DRAG_OVER_TOP: + elm_layout_signal_emit(term_at_coords->bg, + "drag_top,on", "terminology"); + break; + case DRAG_OVER_BOTTOM: + elm_layout_signal_emit(term_at_coords->bg, + "drag_bottom,on", "terminology"); + break; + default: + break; + } + } + _tab_drag->term_over = term_at_coords; + _tab_drag->drag_over = drag_over_position; } static Eina_Bool @@ -6201,6 +6318,11 @@ _term_free(Term *term) { _tab_drag_free(); } + if (_tab_drag && _tab_drag->term_over == term) + { + _tab_drag->term_over = NULL; + _tab_drag->drag_over = DRAG_OVER_NONE; + } if (term->sendfile_request) { evas_object_del(term->sendfile_request);