From 571be6a89a4494937d8a357b52cac5d2cebf66a9 Mon Sep 17 00:00:00 2001 From: "Carsten Haitzler (Rasterman)" Date: Tue, 28 Jan 2014 17:19:25 +0900 Subject: [PATCH] add gesture seeking (drag horizontally + momentum) --- TODO | 2 - src/bin/Makefile.am | 1 + src/bin/gesture.c | 142 ++++++++++++++++++++++++++++++++++++++++++++ src/bin/gesture.h | 6 ++ src/bin/win.c | 3 + src/bin/win.h | 8 ++- 6 files changed, 159 insertions(+), 3 deletions(-) create mode 100644 src/bin/gesture.c create mode 100644 src/bin/gesture.h diff --git a/TODO b/TODO index 86b4da7..1277017 100644 --- a/TODO +++ b/TODO @@ -1,6 +1,4 @@ * volume status display when changed (slider/image/percentage) -* elm gesture drag to left/right for forward/rewind -* elm gesture drag up/down for prev/next * emotion engine selection options * timeline thumbnails on position slider * playlist display + selection from playlist (on left?) diff --git a/src/bin/Makefile.am b/src/bin/Makefile.am index b600081..3b3797c 100644 --- a/src/bin/Makefile.am +++ b/src/bin/Makefile.am @@ -12,6 +12,7 @@ rage_LDADD = @RAGE_LIBS@ rage_SOURCES = \ controls.c controls.h \ dnd.c dnd.h \ +gesture.c gesture.h \ key.c key.h \ main.c main.h \ video.c video.h \ diff --git a/src/bin/gesture.c b/src/bin/gesture.c new file mode 100644 index 0000000..21aae27 --- /dev/null +++ b/src/bin/gesture.c @@ -0,0 +1,142 @@ +#include +#include "main.h" +#include "win.h" +#include "winvid.h" +#include "video.h" +#include "gesture.h" + +static Eina_Bool +_cb_momentum(void *data, double pos) +{ + Inf *inf = evas_object_data_get(data, "inf"); + Evas_Coord w, dx; + Eina_Bool end = EINA_FALSE; + + evas_object_geometry_get(inf->event, NULL, NULL, &w, NULL); + if (pos >= 1.0) end = EINA_TRUE; + pos = ecore_animator_pos_map(pos, ECORE_POS_MAP_DECELERATE_FACTOR, 3.0, 0.0); + + dx = inf->drag_dist + (inf->drag_momentum * pos); + + pos = inf->start_pos + (((dx) * 60.0) / (double)(w / 2)); + video_position_set(inf->vid, pos); + if (end) + { + inf->drag_anim = NULL; + if (inf->was_playing) win_do_play(data); + return EINA_FALSE; + } + return EINA_TRUE; +} + +static Evas_Event_Flags +_cb_long_move(void *data EINA_UNUSED, void *event EINA_UNUSED) +{ + // longpress - options + return EVAS_EVENT_FLAG_ON_HOLD; +} + +static Evas_Event_Flags +_cb_move_start(void *data, void *event EINA_UNUSED) +{ + Inf *inf = evas_object_data_get(data, "inf"); + + if (inf->drag_anim) + { + ecore_animator_del(inf->drag_anim); + inf->drag_anim = NULL; + } + inf->dragging = EINA_FALSE; + return EVAS_EVENT_FLAG_ON_HOLD; +} + +static Evas_Event_Flags +_cb_move_move(void *data, void *event) +{ + Elm_Gesture_Momentum_Info *p = event; + Inf *inf = evas_object_data_get(data, "inf"); + Evas_Coord w, sz = 0, dx; + double pos; + + elm_coords_finger_size_adjust(1, &sz, 1, &sz); + evas_object_geometry_get(inf->event, NULL, NULL, &w, NULL); + if (w < 2) w = 2; + dx = p->x2 - p->x1; + if (abs(dx) < sz) return 0; + if (!inf->dragging) + { + inf->was_playing = inf->playing; + inf->start_pos = video_position_get(inf->vid); + win_do_pause(data); + } + inf->dragging = EINA_TRUE; + pos = inf->start_pos + (((dx) * 60.0) / (double)(w / 2)); + video_position_set(inf->vid, pos); + return EVAS_EVENT_FLAG_ON_HOLD; +} + +static Evas_Event_Flags +_cb_move_end(void *data, void *event) +{ + Elm_Gesture_Momentum_Info *p = event; + Inf *inf = evas_object_data_get(data, "inf"); + + if (inf->dragging) + { + double tim = sqrt((p->mx * p->mx) + (p->my * p->my)) / 1000.0; + + if (tim > 0.0) + { + inf->drag_dist = p->x2 - p->x1; + inf->drag_momentum = p->mx; + inf->drag_time = tim; + inf->drag_start = ecore_loop_time_get(); + inf->drag_anim = + ecore_animator_timeline_add(tim, _cb_momentum, data); + } + else + { + if (inf->was_playing) win_do_play(data); + } + } + else + { + if (inf->was_playing) win_do_play(data); + } + return EVAS_EVENT_FLAG_ON_HOLD; +} + +static Evas_Event_Flags +_cb_move_abort(void *data, void *event EINA_UNUSED) +{ + Inf *inf = evas_object_data_get(data, "inf"); + + if (inf->was_playing) win_do_play(data); + return EVAS_EVENT_FLAG_ON_HOLD; +} + +void +gesture_init(Evas_Object *win, Evas_Object *tgt) +{ + Inf *inf = evas_object_data_get(win, "inf"); + Evas_Object *g; + + inf->glayer = g = elm_gesture_layer_add(win); + elm_gesture_layer_attach(g, tgt); + + elm_gesture_layer_cb_set(g, ELM_GESTURE_N_LONG_TAPS, + ELM_GESTURE_STATE_MOVE, _cb_long_move, + win); + elm_gesture_layer_cb_set(g, ELM_GESTURE_MOMENTUM, + ELM_GESTURE_STATE_START, _cb_move_start, + win); + elm_gesture_layer_cb_set(g, ELM_GESTURE_MOMENTUM, + ELM_GESTURE_STATE_MOVE, _cb_move_move, + win); + elm_gesture_layer_cb_set(g, ELM_GESTURE_MOMENTUM, + ELM_GESTURE_STATE_END, _cb_move_end, + win); + elm_gesture_layer_cb_set(g, ELM_GESTURE_MOMENTUM, + ELM_GESTURE_STATE_ABORT, _cb_move_abort, + win); +} diff --git a/src/bin/gesture.h b/src/bin/gesture.h new file mode 100644 index 0000000..fec5ee8 --- /dev/null +++ b/src/bin/gesture.h @@ -0,0 +1,6 @@ +#ifndef _GESTURE_H__ +#define _GESTURE_H__ 1 + +void gesture_init(Evas_Object *win, Evas_Object *tgt); + +#endif diff --git a/src/bin/win.c b/src/bin/win.c index 77fdd53..58e666e 100644 --- a/src/bin/win.c +++ b/src/bin/win.c @@ -6,6 +6,7 @@ #include "dnd.h" #include "key.h" #include "controls.h" +#include "gesture.h" static void _cb_fullscreen(void *data EINA_UNUSED, Evas_Object *obj, void *event EINA_UNUSED) @@ -29,6 +30,7 @@ _cb_win_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void if (inf->next_job) ecore_job_del(inf->next_job); if (inf->show_timeout) ecore_timer_del(inf->show_timeout); + if (inf->drag_anim) ecore_animator_del(inf->drag_anim); EINA_LIST_FREE(inf->file_list, f) eina_stringshare_del(f); evas_object_data_del(obj, "inf"); free(inf); @@ -265,6 +267,7 @@ win_add(void) evas_object_show(o); inf->event = o; dnd_init(win, o); + gesture_init(win, o); evas_object_event_callback_add(win, EVAS_CALLBACK_KEY_DOWN, _cb_key_down, win); diff --git a/src/bin/win.h b/src/bin/win.h index cc799a7..bfc821b 100644 --- a/src/bin/win.h +++ b/src/bin/win.h @@ -5,16 +5,22 @@ typedef struct _Inf Inf; struct _Inf { - Evas_Object *vid, *lay, *event; + Evas_Object *vid, *lay, *event, *glayer; Eina_List *file_list, *file_cur; Ecore_Job *next_job; Ecore_Timer *show_timeout; + Ecore_Animator *drag_anim; double last_action; double jump; + double start_pos; + double drag_time, drag_start; int zoom_mode; + int drag_dist, drag_momentum; Eina_Bool sized : 1; Eina_Bool last_action_rwind : 1; Eina_Bool playing : 1; + Eina_Bool was_playing : 1; + Eina_Bool dragging : 1; }; // ui high level controls