Enlightenment CVS committal Author : raster Project : e17 Module : apps/e
Dir : e17/apps/e/src/bin Modified Files: e_config.c e_config.h e_fm.c e_ilist.c e_scrollframe.c e_tlist.c Log Message: thumbscroll. the ability to scroll any widget (anything scrolled by the scrollfram smart/widget) using your "finger" anywhere in the view. not useful for desktops. useful for small screen devices - openmoko/n800 etc. are perfect targets. just click and drag with your finger, release. drag fast and releas and you get momentum and it continues for a bit while it slows down. configurable via a new config module. =================================================================== RCS file: /cvs/e/e17/apps/e/src/bin/e_config.c,v retrieving revision 1.279 retrieving revision 1.280 diff -u -3 -r1.279 -r1.280 --- e_config.c 21 Jan 2008 01:22:00 -0000 1.279 +++ e_config.c 23 Jan 2008 09:04:54 -0000 1.280 @@ -576,6 +576,11 @@ E_CONFIG_VAL(D, T, ping_clients_interval, INT); E_CONFIG_VAL(D, T, cache_flush_poll_interval, INT); + + E_CONFIG_VAL(D, T, thumbscroll_enable, INT); + E_CONFIG_VAL(D, T, thumbscroll_threshhold, INT); + E_CONFIG_VAL(D, T, thumbscroll_momentum_threshhold, DOUBLE); + E_CONFIG_VAL(D, T, thumbscroll_friction, DOUBLE); e_config = e_config_domain_load("e", _e_config_edd); if (e_config) @@ -811,6 +816,7 @@ CFG_MODULE("conf_winlist", 1, 1); CFG_MODULE("conf_engine", 1, 1); CFG_MODULE("fileman", 1, 1); + CFG_MODULE("conf_interaction", 1, 1); } #if 0 { @@ -1480,6 +1486,13 @@ IFCFG(0x0123); e_config->ping_clients_interval = 128; e_config->cache_flush_poll_interval = 512; + IFCFGEND; + + IFCFG(0x0124); + e_config->thumbscroll_enable = 0; + e_config->thumbscroll_threshhold = 8; + e_config->thumbscroll_momentum_threshhold = 100.0; + e_config->thumbscroll_friction = 1.0; IFCFGEND; e_config->config_version = E_CONFIG_FILE_VERSION; =================================================================== RCS file: /cvs/e/e17/apps/e/src/bin/e_config.h,v retrieving revision 1.166 retrieving revision 1.167 diff -u -3 -r1.166 -r1.167 --- e_config.h 11 Jan 2008 07:33:55 -0000 1.166 +++ e_config.h 23 Jan 2008 09:04:54 -0000 1.167 @@ -33,7 +33,7 @@ /* increment this whenever a new set of config values are added but the users * config doesn't need to be wiped - simply new values need to be put in */ -#define E_CONFIG_FILE_GENERATION 0x0123 +#define E_CONFIG_FILE_GENERATION 0x0124 #define E_CONFIG_FILE_VERSION ((E_CONFIG_FILE_EPOCH << 16) | E_CONFIG_FILE_GENERATION) #define E_EVAS_ENGINE_DEFAULT 0 @@ -280,6 +280,11 @@ int ping_clients_interval; int cache_flush_poll_interval; // GUI + + int thumbscroll_enable; + int thumbscroll_threshhold; + double thumbscroll_momentum_threshhold; + double thumbscroll_friction; }; struct _E_Config_Module =================================================================== RCS file: /cvs/e/e17/apps/e/src/bin/e_fm.c,v retrieving revision 1.233 retrieving revision 1.234 diff -u -3 -r1.233 -r1.234 --- e_fm.c 4 Jan 2008 03:47:27 -0000 1.233 +++ e_fm.c 23 Jan 2008 09:04:54 -0000 1.234 @@ -5082,9 +5082,11 @@ ic = data; ev = event_info; + if ((ev->button == 1) && (!ic->drag.dnd)) { - _e_fm2_mouse_1_handler(ic, 1, ev->modifiers); + if (!(ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)) + _e_fm2_mouse_1_handler(ic, 1, ev->modifiers); ic->drag.start = 0; ic->drag.dnd = 0; ic->drag.src = 0; @@ -5143,6 +5145,7 @@ E_Fm2_Icon_Info *ici; ic = data; + if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return; ev = event_info; if ((ic->drag.start) && (ic->sd->eobj)) { @@ -5538,12 +5541,15 @@ } if (sel_change) evas_object_smart_callback_call(sd->obj, "selection_change", NULL); - - if (!sd->config->selection.single) + + if (!(ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)) { - sd->selrect.ox = ev->canvas.x; - sd->selrect.oy = ev->canvas.y; - sd->selecting = 1; + if (!sd->config->selection.single) + { + sd->selrect.ox = ev->canvas.x; + sd->selrect.oy = ev->canvas.y; + sd->selecting = 1; + } } } else if (ev->button == 3) @@ -5577,6 +5583,17 @@ sd = data; ev = event_info; + if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) + { + if (sd->selecting) + { + sd->selecting = 0; + sd->selrect.ox = 0; + sd->selrect.oy = 0; + evas_object_hide(sd->sel_rect); + } + return; + } if (!sd->selecting) return; if (ev->cur.canvas.x < sd->selrect.ox) =================================================================== RCS file: /cvs/e/e17/apps/e/src/bin/e_ilist.c,v retrieving revision 1.39 retrieving revision 1.40 diff -u -3 -r1.39 -r1.40 --- e_ilist.c 15 Aug 2007 11:31:36 -0000 1.39 +++ e_ilist.c 23 Jan 2008 09:04:55 -0000 1.40 @@ -17,6 +17,7 @@ int selected; unsigned char selector : 1; unsigned char multi_select : 1; + unsigned char on_hold : 1; }; static void _e_smart_init (void); @@ -44,7 +45,7 @@ } EAPI void -e_ilist_append(Evas_Object *obj, Evas_Object *icon, const char *label, int header, void (*func) (void *data, void *data2), void (*func_hilight) (void *data, void *data2), void *data, void *data2) +e_ilist_append(Evas_Object *obj, Evas_Object *icon, const char *label, int header, void (*func) (void *data, void *data2), void (*func_hilight) (void *data, void *data2), void *data, void *data2) { E_Ilist_Item *si; Evas_Coord mw = 0, mh = 0; @@ -390,7 +391,10 @@ edje_object_signal_emit(si->o_base, "e,state,selected", "e"); if (si->func_hilight) si->func_hilight(si->data, si->data2); if (sd->selector) return; - if (si->func) si->func(si->data, si->data2); + if (!sd->on_hold) + { + if (si->func) si->func(si->data, si->data2); + } } EAPI int @@ -666,7 +670,10 @@ si->selected = 0; if (si->func_hilight) si->func_hilight(si->data, si->data2); if (sd->selector) return; - if (si->func) si->func(si->data, si->data2); + if (!sd->on_hold) + { + if (si->func) si->func(si->data, si->data2); + } return; } si->selected = 1; @@ -674,7 +681,10 @@ edje_object_signal_emit(si->o_base, "e,state,selected", "e"); if (si->func_hilight) si->func_hilight(si->data, si->data2); if (sd->selector) return; - if (si->func) si->func(si->data, si->data2); + if (!sd->on_hold) + { + if (si->func) si->func(si->data, si->data2); + } } EAPI void @@ -841,6 +851,9 @@ si = data; sd = si->sd; + if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) sd->on_hold = 1; + else sd->on_hold = 0; + if (si->header) return; if (!sd->items) return; for (i = 0, l = sd->items; l; l = l->next, i++) @@ -876,12 +889,20 @@ ev = event_info; si = data; sd = si->sd; + + if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) sd->on_hold = 1; + else sd->on_hold = 0; if (si->header) return; if (!sd->items) return; if (!sd->selector) return; si = evas_list_nth(sd->items, sd->selected); if (!si) return; + if (sd->on_hold) + { + sd->on_hold = 0; + return; + } if (si->func) si->func(si->data, si->data2); } @@ -896,6 +917,10 @@ sd = data; ev = event_info; ns = sd->selected; + + if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) sd->on_hold = 1; + else sd->on_hold = 0; + if ((!strcmp(ev->keyname, "Up")) || (!strcmp(ev->keyname, "KP_Up"))) { n = ns; @@ -1004,10 +1029,14 @@ (!strcmp(ev->keyname, "KP_Enter")) || (!strcmp(ev->keyname, "space"))) { - si = evas_list_nth(sd->items, sd->selected); - if (si) + if (!sd->on_hold) { - if (si->func) si->func(si->data, si->data2); + si = evas_list_nth(sd->items, sd->selected); + if (si) + { + if (si->func) si->func(si->data, si->data2); + } } } + sd->on_hold = 0; } =================================================================== RCS file: /cvs/e/e17/apps/e/src/bin/e_scrollframe.c,v retrieving revision 1.18 retrieving revision 1.19 diff -u -3 -r1.18 -r1.19 --- e_scrollframe.c 4 Aug 2007 13:12:41 -0000 1.18 +++ e_scrollframe.c 23 Jan 2008 09:04:55 -0000 1.19 @@ -19,6 +19,20 @@ Evas_Object *event_obj; E_Scrollframe_Policy hbar_flags, vbar_flags; + + struct { + unsigned char now : 1; + unsigned char dragged : 1; + Evas_Coord x, y; + Evas_Coord sx, sy; + Evas_Coord dx, dy; + struct { + Evas_Coord x, y; + double timestamp; + } history[20]; + double anim_start; + Ecore_Animator *momentum_animator; + } down; struct { Evas_Coord w, h; @@ -34,6 +48,7 @@ void (*child_size_get) (Evas_Object *obj, Evas_Coord *x, Evas_Coord *y); } pan_func; + unsigned char hbar_visible : 1; unsigned char vbar_visible : 1; unsigned char extern_pan : 1; @@ -44,6 +59,9 @@ static void _e_smart_pan_changed_hook(void *data, Evas_Object *obj, void *event_info); static void _e_smart_pan_pan_changed_hook(void *data, Evas_Object *obj, void *event_info); static void _e_smart_event_wheel(void *data, Evas *e, Evas_Object *obj, void *event_info); +static void _e_smart_event_mouse_down(void *data, Evas *e, Evas_Object *obj, void *event_info); +static void _e_smart_event_mouse_up(void *data, Evas *e, Evas_Object *obj, void *event_info); +static void _e_smart_event_mouse_move(void *data, Evas *e, Evas_Object *obj, void *event_info); static void _e_smart_event_key_down(void *data, Evas *e, Evas_Object *obj, void *event_info); static void _e_smart_edje_drag_v(void *data, Evas_Object *obj, const char *emission, const char *source); static void _e_smart_edje_drag_h(void *data, Evas_Object *obj, const char *emission, const char *source); @@ -383,6 +401,168 @@ } static void +_e_smart_event_mouse_down(void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + Evas_Event_Mouse_Down *ev; + E_Smart_Data *sd; + Evas_Coord x = 0, y = 0; + + sd = data; + ev = event_info; + if (e_config->thumbscroll_enable) + { + if (sd->down.momentum_animator) + { + ecore_animator_del(sd->down.momentum_animator); + sd->down.momentum_animator = NULL; + } + if (ev->button == 1) + { + sd->down.now = 1; + sd->down.dragged = 0; + sd->down.x = ev->canvas.x; + sd->down.y = ev->canvas.y; + e_scrollframe_child_pos_get(sd->smart_obj, &x, &y); + sd->down.sx = x; + sd->down.sy = y; + memset(&(sd->down.history[0]), 0, sizeof(sd->down.history[0]) * 20); + sd->down.history[0].timestamp = ecore_time_get(); + sd->down.history[0].x = ev->canvas.x; + sd->down.history[0].y = ev->canvas.y; + } + } +} + +static int +_e_cb_momentum_animator(void *data) +{ + E_Smart_Data *sd; + double t, dt, p; + Evas_Coord x, y, dx, dy; + + sd = data; + t = ecore_time_get(); + dt = t - sd->down.anim_start; + if (dt >= 0.0) + { + dt = dt / e_config->thumbscroll_friction; + if (dt > 1.0) dt = 1.0; + p = 1.0 - ((1.0 - dt) * (1.0 - dt) * (1.0 - dt)); + dx = (sd->down.dx * e_config->thumbscroll_friction * p); + dy = (sd->down.dy * e_config->thumbscroll_friction * p); + x = sd->down.sx - dx; + y = sd->down.sy - dy; + e_scrollframe_child_pos_set(sd->smart_obj, x, y); + if (dt >= 1.0) + { + sd->down.momentum_animator = NULL; + return 0; + } + } + return 1; +} + +static void +_e_smart_event_mouse_up(void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + Evas_Event_Mouse_Down *ev; + E_Smart_Data *sd; + Evas_Coord x = 0, y = 0; + + sd = data; + ev = event_info; + if (e_config->thumbscroll_enable) + { + if (ev->button == 1) + { + + x = ev->canvas.x - sd->down.x; + y = ev->canvas.y - sd->down.y; + if (sd->down.dragged) + { + double t, at, dt; + int i; + Evas_Coord ax, ay, dx, dy, vel; + + t = ecore_time_get(); + ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; + ax = ev->canvas.x; + ay = ev->canvas.y; + at = 0.0; + for (i = 0; i < 20; i++) + { + dt = t - sd->down.history[i].timestamp; + if (dt > 0.2) break; + at += dt; + ax += sd->down.history[i].x; + ay += sd->down.history[i].y; + } + ax /= (i + 1); + ay /= (i + 1); + at /= (i + 1); + at *= 4.0; + dx = ev->canvas.x - ax; + dy = ev->canvas.y - ay; + if (at > 0) + { + vel = sqrt((dx * dx) + (dy * dy)) / at; + if ((e_config->thumbscroll_friction > 0.0) && + (vel > e_config->thumbscroll_momentum_threshhold)) + { + if (!sd->down.momentum_animator) + sd->down.momentum_animator = ecore_animator_add(_e_cb_momentum_animator, sd); + sd->down.dx = ((double)dx / at); + sd->down.dy = ((double)dy / at); + sd->down.anim_start = t; + e_scrollframe_child_pos_get(sd->smart_obj, &x, &y); + sd->down.sx = x; + sd->down.sy = y; + } + } + } + sd->down.dragged = 0; + sd->down.now = 0; + } + } +} + +static void +_e_smart_event_mouse_move(void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + Evas_Event_Mouse_Move *ev; + E_Smart_Data *sd; + Evas_Coord x = 0, y = 0; + + sd = data; + ev = event_info; + if (e_config->thumbscroll_enable) + { + if (sd->down.now) + { + memmove(&(sd->down.history[1]), &(sd->down.history[0]), + sizeof(sd->down.history[0]) * 19); + sd->down.history[0].timestamp = ecore_time_get(); + sd->down.history[0].x = ev->cur.canvas.x; + sd->down.history[0].y = ev->cur.canvas.y; + + x = ev->cur.canvas.x - sd->down.x; + y = ev->cur.canvas.y - sd->down.y; + if ((sd->down.dragged) || + (((x * x) + (y * y)) > + (e_config->thumbscroll_threshhold * + e_config->thumbscroll_threshhold))) + { + ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; + sd->down.dragged = 1; + } + x = sd->down.sx - (ev->cur.canvas.x - sd->down.x); + y = sd->down.sy - (ev->cur.canvas.y - sd->down.y); + e_scrollframe_child_pos_set(sd->smart_obj, x, y); + } + } +} + +static void _e_smart_event_key_down(void *data, Evas *e, Evas_Object *obj, void *event_info) { Evas_Event_Key_Down *ev; @@ -698,6 +878,9 @@ sd->event_obj = o; evas_object_color_set(o, 0, 0, 0, 0); evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_WHEEL, _e_smart_event_wheel, sd); + evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_DOWN, _e_smart_event_mouse_down, sd); + evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_UP, _e_smart_event_mouse_up, sd); + evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_MOVE, _e_smart_event_mouse_move, sd); evas_object_smart_member_add(o, obj); evas_object_repeat_events_set(o, 1); @@ -717,6 +900,7 @@ if (!sd->extern_pan) evas_object_del(sd->pan_obj); evas_object_del(sd->edje_obj); evas_object_del(sd->event_obj); + if (sd->down.momentum_animator) ecore_animator_del(sd->down.momentum_animator); free(sd); } =================================================================== RCS file: /cvs/e/e17/apps/e/src/bin/e_tlist.c,v retrieving revision 1.8 retrieving revision 1.9 diff -u -3 -r1.8 -r1.9 --- e_tlist.c 4 Aug 2007 13:12:41 -0000 1.8 +++ e_tlist.c 23 Jan 2008 09:04:55 -0000 1.9 @@ -20,7 +20,8 @@ Evas_Object *box_obj; Evas_List *items; int selected; - unsigned char selector:1; + unsigned char selector : 1; + unsigned char on_hold : 1; }; struct _E_Smart_Item @@ -121,8 +122,11 @@ si->func_hilight(si->data, si->data2); if (!sd->selector) { - if (si->func) - si->func(si->data, si->data2); + if (!sd->on_hold) + { + if (si->func) + si->func(si->data, si->data2); + } } } } @@ -369,6 +373,10 @@ si = data; ev = event_info; + + if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) si->sd->on_hold = 1; + else si->sd->on_hold = 0; + for (i = 0, l = si->sd->items; l; l = l->next, i++) { if (l->data == si) @@ -388,15 +396,22 @@ si = data; ev = event_info; + if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) si->sd->on_hold = 1; + else si->sd->on_hold = 0; + if (si->sd->selector) { si = evas_list_nth(si->sd->items, si->sd->selected); if (si) { - if (si->func) - si->func(si->data, si->data2); + if (!si->sd->on_hold) + { + if (si->func) + si->func(si->data, si->data2); + } } } + si->sd->on_hold = 0; } static void @@ -424,13 +439,16 @@ } else if ((!strcmp(ev->keyname, "Return")) || (!strcmp(ev->keyname, "space"))) { - E_Smart_Item *si; - - si = evas_list_nth(sd->items, sd->selected); - if (si) + if (!sd->on_hold) { - if (si->func) - si->func(si->data, si->data2); + E_Smart_Item *si; + + si = evas_list_nth(sd->items, sd->selected); + if (si) + { + if (si->func) + si->func(si->data, si->data2); + } } } } ------------------------------------------------------------------------- This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2008. http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ _______________________________________________ enlightenment-cvs mailing list enlightenment-cvs@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/enlightenment-cvs